Testa den här frågan:
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 --- en förklaring av hur frågan fungerar (eller snarare varför din fråga inte fungerar) ----
Om man tittar på förväntade resultat verkar det som att frågan bör beräkna summan av amount
kolumn för varje user_id
, men bara för dessa user_id
, som också finns i blocks
tabell och har en blocks.confirms
värde större än 520.
En enkel koppling (även vänster yttre koppling) kan inte fungera i det här fallet, eftersom blocks
Tabell kan innehålla många poster för samma user_id
, till exempel en fråga som returnerar rader för endast user_id=110
ger följande resultat:
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 |
+ ------- + ------------ + ----------- + ------------- +
Den raka kopplingen (och LEFT/RIGHT yttre kopplingen) fungerar på det här sättet, som tar varje post från den första sammanfogade tabellen, och para denna post (kombinera den) med alla rader från den andra sammanfogade tabellen som uppfyller kopplingsvillkoret.
I vårt fall ger den vänstra kopplingen följande resultat:
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 |
+ ------- + ------- + ----------- + -------- + --- + ------- + ----------- +
och nu om vi lägger till SUM( amount ) .... GROUP BY user_id
, kommer MySql att beräkna summan av alla amount
värden från ovanstående resultatuppsättning ( 8 rader * 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 |
+ ------------ + ----------------- +
Som du ser i det här fallet ger anslutningen inte önskat resultat - vi behöver något som heter a semi join
- nedan är olika varianter av semi joins, prova dem:
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
;