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.