Joins behandles fra venstre mod højre (medmindre andet er angivet i parenteser). Hvis du LEFT JOIN
(eller bare JOIN
, lignende effekt) tre dagligvarer til én bruger får du 3 rækker (1 x 3 ). Hvis du så tilmelder dig 4 fiskemarkeder for den samme bruger, får du 12 (3 x 4 ) rækker, multiplicerer den tidligere optælling i resultatet, ikke tilføjelse til det, som du måske havde håbet på.
Derved mangedobles besøgene for både dagligvarer og fiskemarkeder.
Du kan få det til at virke sådan her:
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;
For at få aggregerede værdier for en eller få brugere, korrelerede underforespørgsler ligesom @Vince forudsat er helt fint. For en hel tabel eller større dele af den er det (meget) mere effektivt at samle n-tabellerne og slutte sig til resultatet en gang . På denne måde behøver vi heller ikke en anden GROUP BY
i den ydre forespørgsel.
grocery_visits
og fishmarket_visits
er NULL
for brugere uden relaterede poster i de respektive tabeller. Hvis du har brug for 0
i stedet (eller et hvilket som helst vilkårligt tal), brug COALESCE
i den ydre SELECT
:
SELECT u.id
, u.account_balance
, COALESCE(g.grocery_visits , 0) AS grocery_visits
, COALESCE(f.fishmarket_visits, 0) AS fishmarket_visits
FROM ...