【问题标题】:combining mysql query SUM() result using inner join使用内部连接组合 mysql 查询 SUM() 结果
【发布时间】:2011-11-03 00:57:04
【问题描述】:

我有这两张表

table1 : date | uid | value_in
table2 : date | uid | value_out 

每天,无论交易/记录的数量如何,每个 uid 都会收到进出的余额值

我想做的是将查询结果组合成这样

date | uid | value_in | value_out | (value_in-value_out) as balance

但是,当我执行此查询时

SELECT 
  a.date,
  a.uid,
  SUM(a.value_in),
  SUM(b.value_out),
  (SUM(a.value_in)-SUM(b.value_out)) AS balance
FROM table1 a
INNER JOIN table2 b ON a.date=b.date AND a.uid=b.uid
GROUP BY a.date, a.uid

它产生无效的结果(SUM 是两倍或三倍) 我应该如何修改我的查询,使其不会产生双倍的结果?

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    首先建立总和,然后加入。像这样:

    SELECT i.uid
          ,i.date
          ,i.v_in
          ,COALESCE(o.v_out, 0) AS v_out
          ,(i.v_in - COALESCE(o.v_out, 0)) AS balance
    FROM (
        SELECT date
              ,uid
              ,SUM(value_in) AS v_in
        FROM   table1
        GROUP  BY 1,2
        ) i
    LEFT JOIN (
        SELECT date
              ,uid
              ,SUM(value_out) AS v_out
        FROM   table2
        GROUP  BY 1,2
        ) o USING (date, uid)
    

    按照您的方式,每个 value_in 将与每个匹配的 value_out 组合,从而使数字相乘。你必须先聚合,然后加入 one in-sum 和 one out-sum,一切都很正常。还是这样?

    如果给定的(date, uid) 没有value_invalue_out,会发生什么?还是只有value_in 或者只是value_out?您的查询将失败。

    我通过使用LEFT JOIN 而不是[INNER] JOIN 进行了改进,但您真正想要的是FULL OUTER JOIN - MySQL 中缺少的功能之一。

    您可以在单独的表格和LEFT JOIN 两个表格中提供日期列表,或者您可以使用两次LEFT JOINUNION 来解决缺少的功能。 See here for an example.

    或者您可以将value_out 乘以-1 UNION 两个表并得到一个总和。

    但是如果没有value_invalue_out,你仍然不会得到一排,这违反了你的描述。

    所以,唯一干净的解决方案是有一个表格,其中包含您想要的所有(date, uid) 结果和LEFT JOIN table1table2 的总和,或者@ 987654344@这三个(负table2)在一个子中选择然后求和。

    【讨论】:

    • 哇,它正在工作。比INNER JOIN更好更快,我需要学习这种查询。谢谢
    • @skeith:我添加了一些改进和修复。你可能想看看。
    • 是的,再次感谢您提供的改进和修复,它超出了我的预期,会从中学习(我觉得它对我来说太先进了)
    【解决方案2】:

    如果你尝试这个会有什么结果

    SELECT 
      a.date,
      a.uid,
      SUM(a.value_in),
      SUM(b.value_out),
      SUM(a.value_in-b.value_out) AS balance 
    FROM table1 a
    INNER JOIN table2 b ON a.date=b.date AND a.uid=b.uid
    GROUP BY a.date, a.uid
    

    SUM(a.value_in-b.value_out) AS balance 应该在逻辑上与(SUM(a.value_in)-SUM(b.value_out)) AS balance 相同,但可能与 mysql 不同

    【讨论】:

    • 我在发布我的问题之前也尝试过这个查询,但仍然会产生类似的无效结果
    • 你可能在第二个表中有负值
    • @MilanJaric:阅读我的答案,了解为什么会失败。
    • 是的,我明白了,最后我意识到,对于每个标准日期,uid,两个表中的行数都不相同。好想法@ErwinBrandstetter
    • 正如我在问题上解释的那样,每次进出的交易记录可能不一样。但是,它应该遵循一个规则,即 in-out 应该是 0(零)
    【解决方案3】:
    SELECT 
      a.date,
      a.uid,
      SUM(a.value_in),
      SUM(b.value_out),
      SUM(a.value_in-b.value_out) AS balance 
    FROM table1 a
    INNER JOIN table2 b ON a.date=b.date AND a.uid=b.uid
    GROUP BY a.date, a.uid`enter code here`
    

    【讨论】:

      猜你喜欢
      • 2015-03-10
      • 2020-09-06
      • 2022-01-24
      • 1970-01-01
      • 2016-03-08
      • 1970-01-01
      • 2012-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多