Joins worden van links naar rechts verwerkt (tenzij haakjes anders aangeven). Als je LEFT JOIN
(of gewoon JOIN
, soortgelijk effect) drie boodschappen voor één gebruiker krijg je 3 rijen (1 x 3 ). Als je dan lid wordt van 4 vismarkten voor dezelfde gebruiker, krijg je 12 (3 x 4 ) rijen, vermenigvuldigen de vorige telling in het resultaat, niet toevoegen ernaar toe, zoals je misschien had gehoopt.
Daardoor vermenigvuldigen de bezoeken voor zowel boodschappen als vismarkten.
Je kunt het als volgt laten werken:
SELECT u.id
, u.account_balance
, g.grocery_visits
, f.fishmarket_visits
FROM users u
LEFT JOIN (
SELECT user_id, count(*) AS grocery_visits
FROM grocery
GROUP BY user_id
) g ON g.user_id = u.id
LEFT JOIN (
SELECT user_id, count(*) AS fishmarket_visits
FROM fishmarket
GROUP BY user_id
) f ON f.user_id = u.id
ORDER BY u.id;
Om geaggregeerde waarden voor een of enkele gebruikers te krijgen, gecorreleerde subquery's zoals @Vince verstrekt zijn prima. Voor een hele tabel of grote delen ervan is het (veel) efficiënter om de n-tabellen samen te voegen en eenmaal aan het resultaat toe te voegen . Op deze manier hebben we ook geen andere GROUP BY
nodig in de buitenste vraag.
grocery_visits
en fishmarket_visits
zijn NULL
voor gebruikers zonder gerelateerde vermeldingen in de respectievelijke tabellen. Als je 0
nodig hebt gebruik in plaats daarvan (of een willekeurig nummer) COALESCE
in de buitenste SELECT
:
SELECT u.id
, u.account_balance
, COALESCE(g.grocery_visits , 0) AS grocery_visits
, COALESCE(f.fishmarket_visits, 0) AS fishmarket_visits
FROM ...