Um Ihre Logik zu vereinfachen, aggregieren Sie zuerst und treten Sie später bei.
Wenn Sie fehlende Details erraten, würde Ihnen diese Abfrage die genaue Anzahl liefern, wie oft auf jeden Benutzer in table1 verwiesen wurde und table2 bzw. für alle Benutzer :
SELECT *
FROM users u
LEFT JOIN (
SELECT updated_by_id AS id, count(*) AS t1_ct
FROM table1
GROUP BY 1
) t1 USING (id)
LEFT JOIN (
SELECT updated_by_id AS id, count(*) AS t2_ct
FROM table2
GROUP BY 1
) t2 USING (id);
Vermeiden Sie insbesondere, dass sich mehrere 1-n-Beziehungen gegenseitig multiplizieren, wenn sie miteinander verbunden werden:
Um einen einzelnen oder wenige Benutzer abzurufen nur LATERAL Joins werden schneller sein (Postgres 9.3+):
SELECT *
FROM users u
LEFT JOIN LATERAL (
SELECT count(*) AS t1_ct
FROM table1
WHERE updated_by_id = u.id
) ON true
LEFT JOIN LATERAL (
SELECT count(*) AS t2_ct
FROM table2
WHERE updated_by_id = u.id
) ON true
WHERE u.id = 100;
Erklären Sie den wahrgenommenen Unterschied
Die besondere Nichtübereinstimmung, die Sie melden, ist auf die Besonderheiten eines FULL OUTER JOIN
:
So bekommt man für fehlende Übereinstimmungen auf der jeweils anderen Seite NULL-Werte angehängt. count() zählt keine NULL-Werte. Sie können also ein anderes Ergebnis erhalten, je nachdem, ob Sie nach u1.id=100 filtern oder u2.id=100 .
Dies nur zur Erklärung, Sie brauchen keinen FULL JOIN hier. Verwenden Sie stattdessen die vorgestellten Alternativen.