Đầu tiên xây dựng tổng, sau đó tham gia. Như thế này:
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)
Theo cách bạn có, mọi value_in
sẽ được kết hợp với mọi value_out
phù hợp , do đó nhân các số. Trước tiên, bạn phải tổng hợp và sau đó bạn tham gia một tổng bằng một tổng cộng và mọi thứ đều hấp dẫn. Hay là nó?
Điều gì xảy ra nếu không có value_in
hoặc value_out
cho một (date, uid)
nhất định ? Hoặc chỉ value_in
Hoặc chỉ value_out
? Truy vấn của bạn sẽ không thành công.
Tôi đã cải thiện bằng cách sử dụng LEFT JOIN
thay vì [INNER] JOIN
, nhưng những gì bạn thực sự muốn là một FULL OUTER JOIN
- một trong những tính năng còn thiếu trong MySQL.
Bạn có thể cung cấp danh sách các ngày trong một bảng riêng biệt và LEFT JOIN
cả hai bảng cho nó hoặc bạn có thể khắc phục tính năng bị thiếu với hai lần LEFT JOIN
và UNION
. Xem tại đây cho một ví dụ
.
Hoặc bạn có thể nhân value_out
của mình bởi -1
UNION cả hai bảng lại với nhau và tạo một tổng.
Nhưng bạn vẫn sẽ không nhận được một hàng trong một ngày mà không có bất kỳ value_in
nào hoặc value_out
, vi phạm mô tả của bạn.
Vì vậy, giải pháp sạch duy nhất là có một bảng với tất cả (date, uid)
bạn muốn trong kết quả và LEFT JOIN
tổng của table1
và table2
với nó, hoặc UNION ALL
ba (table2
phủ định ) trong một lựa chọn phụ và sau đó tổng hợp.