PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Zählen Sie Zeilen nach dem Verbinden von drei Tabellen in PostgreSQL

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.