我有这两张表
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是两倍或三倍),我应该如何修改查询以使其不会产生两倍的结果?
首先建立总和,然后加入。像这样:
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,从而使数字相乘。您必须先进行汇总,然后再将 一个 总和与 一个 总和结合在一起,否则一切都会变得古怪。还是吗?
value_in
value_out
如果没有给定的value_in或value_out给定的会发生什么(date,uid)?还是只有value_in还是只是value_out?您的查询将失败。
(date,uid)
我通过使用LEFT JOIN而不是进行了改进[INNER] JOIN,但是您真正想要的是FULL OUTERJOIN-MySQL中缺少的功能之一。
LEFT JOIN
[INNER] JOIN
FULL OUTERJOIN
您可以提供一个单独的表天,清单LEFT JOIN两个表到它,或者你可以解决缺少的功能,以两次LEFT JOIN和UNION。请参阅此处的示例。
UNION
或者, 你可以增加你value_out的-1UNION两个表一起,构建一个总和。
-1
但是,如果没有任何一天或一天,您 仍然 不会连续一天,这违反了您的描述。value_in``value_out
value_in``value_out
因此, 唯一干净的解决方案 是(date, uid)在结果中加上所需的所有LEFT JOIN内容table1以及table2与之和的表,或者在子选择中包含UNION ALL三个(负数table2)的表,然后进行汇总。
(date, uid)
table1
table2
UNION ALL