我有这两张桌子
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加倍或三倍) 我应该如何修改我的查询,以便它不会产生加倍的结果?
答案 0 :(得分:3)
首先构建总和,然后加入。像这样:
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
或(date, uid)
会怎样?或者仅value_in
或仅value_out
?您的查询将失败。
我使用LEFT JOIN
代替[INNER] JOIN
进行了改进,但您真正想要的是FULL OUTER JOIN
- MySQL中缺少的功能之一。
您可以在单独的表格中提供天数列表,也可以在LEFT JOIN
两个表格中提供,或者您可以使用LEFT JOIN
和UNION
两次解决缺失的功能。 See here for an example
或您可以将value_out
和-1
两个表格相乘,并构建一个总和。
但仍然不会在没有任何value_in
或value_out
的情况下获得一行,这违反了您的描述。
因此,唯一干净的解决方案是在结果中包含您想要的所有(date, uid)
的表格,LEFT JOIN
是table1
和{{的总和1}},或者table2
子选项中的三个(负UNION ALL
),然后总结。
答案 1 :(得分:0)
如果您尝试这样做会产生什么结果
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
答案 2 :(得分:0)
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`