I join vengono elaborati da sinistra a destra (a meno che le parentesi non indichino diversamente). Se LEFT JOIN
(o semplicemente JOIN
, effetto simile) tre generi alimentari a un utente ottieni 3 righe (1 x 3 ). Se poi ti unisci a 4 mercati ittici per lo stesso utente, ne ricevi 12 (3 x 4 ) righe, moltiplicando il conteggio precedente nel risultato, non aggiungendo ad esso, come forse avevi sperato.
Moltiplicando così le visite per generi alimentari e pescherie allo stesso modo.
Puoi farlo funzionare in questo modo:
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;
Per ottenere valori aggregati per uno o pochi utenti, sottoquery correlate come @Vince fornito vanno bene. Per un'intera tabella o parti principali di essa, è (molto) più efficiente aggregare le n-tabelle e unirle al risultato una volta . In questo modo, non abbiamo nemmeno bisogno di un altro GROUP BY
nella query esterna.
grocery_visits
e fishmarket_visits
sono NULL
per gli utenti senza voci correlate nelle rispettive tabelle. Se hai bisogno di 0
invece (o qualsiasi numero arbitrario), usa COALESCE
nel SELECT
esterno :
SELECT u.id
, u.account_balance
, COALESCE(g.grocery_visits , 0) AS grocery_visits
, COALESCE(f.fishmarket_visits, 0) AS fishmarket_visits
FROM ...