Joins werden von links nach rechts verarbeitet (es sei denn, Klammern schreiben etwas anderes vor). Wenn Sie LEFT JOIN
(oder einfach JOIN
, ähnlicher Effekt) drei Lebensmittel für einen Benutzer erhalten Sie 3 Zeilen (1 x 3 ). Wenn Sie dann 4 Fischmärkten für denselben Benutzer beitreten, erhalten Sie 12 (3 x 4 ) Zeilen, Multiplizieren die vorherige Zählung im Ergebnis, nicht Hinzufügen dazu, wie Sie es sich vielleicht erhofft haben.
Dadurch vervielfachen sich die Besuche für Lebensmittel und Fischmärkte gleichermaßen.
Sie können es so machen:
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;
Um aggregierte Werte für einen oder wenige Benutzer zu erhalten, korrelieren Sie Unterabfragen wie @Vince vorausgesetzt, sind in Ordnung. Für eine ganze Tabelle oder größere Teile davon ist es (viel) effizienter, die n-Tabellen zu aggregieren und einmal mit dem Ergebnis zu verknüpfen . Auf diese Weise brauchen wir auch kein weiteres GROUP BY
in der äußeren Abfrage.
grocery_visits
und fishmarket_visits
sind NULL
für Benutzer ohne entsprechende Einträge in den jeweiligen Tabellen. Wenn Sie 0
benötigen Verwenden Sie stattdessen (oder eine beliebige Zahl) COALESCE
im äußeren SELECT
:
SELECT u.id
, u.account_balance
, COALESCE(g.grocery_visits , 0) AS grocery_visits
, COALESCE(f.fishmarket_visits, 0) AS fishmarket_visits
FROM ...