Pertama membangun jumlah, kemudian bergabung. Seperti ini:
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)
Cara Anda memilikinya, setiap value_in
akan digabungkan dengan setiap value_out
yang cocok , sehingga mengalikan angka. Anda harus menggabungkan terlebih dahulu dan kemudian Anda bergabung dengan satu in-sum dengan satu out-sum dan semuanya asyik. Atau itu?
Apa yang terjadi jika tidak ada value_in
atau value_out
untuk (date, uid)
yang diberikan ? Atau hanya value_in
Atau cukup value_out
? Permintaan Anda akan gagal.
Saya meningkatkan dengan menggunakan LEFT JOIN
bukannya [INNER] JOIN
, tetapi yang Anda inginkan adalah FULL OUTER JOIN
- salah satu fitur yang hilang di MySQL.
Anda dapat memberikan daftar hari dalam tabel terpisah dan LEFT JOIN
kedua tabel untuk itu, atau Anda dapat mengatasi fitur yang hilang dengan dua kali LEFT JOIN
dan UNION
. Lihat di sini sebagai contoh
.
Atau Anda dapat melipatgandakan value_out
oleh -1
Gabungkan kedua tabel dan buat satu penjumlahan.
Tapi Anda tetap tidak akan mendapatkan baris selama sehari tanpa value_in
atau value_out
, yang melanggar deskripsi Anda.
Jadi, satu-satunya solusi bersih adalah memiliki tabel dengan semua (date, uid)
yang Anda inginkan dalam hasil dan LEFT JOIN
jumlah table1
dan table2
untuk itu, atau UNION ALL
ketiganya (negatif table2
) dalam sub-pilihan lalu jumlahkan.