Coba kueri ini:
SELECT bl.user_id, SUM( ph.amount ) PAIDOUT
FROM (
SELECT distinct blocks.user_id
FROM blocks
WHERE confirms > 520
) bl
LEFT JOIN payout_history ph
ON bl.user_id = ph.user_id
GROUP BY ph.user_id
;
SQLFiddle --> http://sqlfiddle.com/#!2/7b988/48
--- EDIT --- penjelasan cara kerja kueri (atau lebih tepatnya mengapa kueri Anda tidak berfungsi) ----
Melihat hasil yang diharapkan, tampaknya kueri harus menghitung jumlah amount
kolom untuk setiap user_id
, tetapi hanya untuk user_id
tersebut , yang juga ada di blocks
tabel, dan memiliki blocks.confirms
nilai lebih dari 520.
Gabungan sederhana (juga gabungan luar kiri) tidak dapat bekerja dalam kasus ini, karena blocks
tabel dapat berisi banyak record untuk user_id
yang sama , misalnya kueri yang mengembalikan baris hanya untuk user_id=110
memberikan hasil sebagai berikut:
SELECT *
FROM blocks
WHERE confirms > 520
AND user_id = 110;
+ ------- + ------------ + ----------- + ------------- +
| id | user_id | reward | confirms |
+ ------- + ------------ + ----------- + ------------- +
| 0 | 110 | 20.89832115 | 521 |
| 65174 | 110 | 3.80357075 | 698 |
| 65204 | 110 | 4.41933060 | 668 |
| 65218 | 110 | 4.69059801 | 654 |
| 65219 | 110 | 4.70222521 | 653 |
| 65230 | 110 | 4.82805490 | 642 |
| 65265 | 110 | 5.25058079 | 607 |
| 65316 | 110 | 6.17262650 | 556 |
+ ------- + ------------ + ----------- + ------------- +
Penggabungan lurus (dan gabungan luar KIRI/KANAN) bekerja dengan cara ini, yang mengambil setiap record dari tabel join pertama, dan memasangkan record ini (menggabungkannya) dengan semua baris dari tabel join lainnya yang memenuhi kondisi join.
Dalam kasus kami, gabungan kiri menghasilkan hasil di bawah ini:
SELECT *
FROM blocks
LEFT JOIN payout_history
ON blocks.user_id = payout_history.user_id
WHERE confirms > 520
AND blocks.user_id = 110;
+ ------- + ------- + ----------- + -------- + --- + ------- + ----------- +
| id | user_id | reward | confirms | id | user_id | amount |
+ ------- + ------- + ----------- + -------- + --- + ------- + ----------- +
| 0 | 110 | 20.89832115 | 521 | 1 | 110 | 20.898319 |
| 65174 | 110 | 3.80357075 | 698 | 1 | 110 | 20.898319 |
| 65204 | 110 | 4.41933060 | 668 | 1 | 110 | 20.898319 |
| 65218 | 110 | 4.69059801 | 654 | 1 | 110 | 20.898319 |
| 65219 | 110 | 4.70222521 | 653 | 1 | 110 | 20.898319 |
| 65230 | 110 | 4.82805490 | 642 | 1 | 110 | 20.898319 |
| 65265 | 110 | 5.25058079 | 607 | 1 | 110 | 20.898319 |
| 65316 | 110 | 6.17262650 | 556 | 1 | 110 | 20.898319 |
+ ------- + ------- + ----------- + -------- + --- + ------- + ----------- +
dan sekarang jika kita menambahkan SUM( amount ) .... GROUP BY user_id
, MySql akan menghitung jumlah semua amount
nilai dari hasil di atas (8 baris * 20.898 =~ 167.184 )
SELECT blocks.user_id, sum( amount)
FROM blocks
LEFT JOIN payout_history
ON blocks.user_id = payout_history.user_id
WHERE confirms > 520
AND blocks.user_id = 110
GROUP BY blocks.user_id;
+ ------------ + ----------------- +
| user_id | sum( amount) |
+ ------------ + ----------------- +
| 110 | 167.186554 |
+ ------------ + ----------------- +
Seperti yang Anda lihat dalam kasus ini join tidak memberikan hasil yang diinginkan - kita membutuhkan sesuatu yang bernama a semi join
- di bawah ini adalah varian yang berbeda dari semi join, cobalah:
SELECT bl.user_id, SUM( ph.amount ) PAIDOUT
FROM (
SELECT distinct blocks.user_id
FROM blocks
WHERE confirms > 520
) bl
LEFT JOIN payout_history ph
ON bl.user_id = ph.user_id
GROUP BY ph.user_id
;
SELECT ph.user_id, SUM( ph.amount ) PAIDOUT
FROM payout_history ph
WHERE ph.user_id IN (
SELECT user_id FROM blocks
WHERE confirms > 520
)
GROUP BY ph.user_id
;
SELECT ph.user_id, SUM( ph.amount ) PAIDOUT
FROM payout_history ph
WHERE EXISTS (
SELECT 1 FROM blocks bl
WHERE bl.user_id = ph.user_id
AND bl.confirms > 520
)
GROUP BY ph.user_id
;