PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Compter les lignes après avoir joint trois tables dans PostgreSQL

Pour simplifier votre logique, agrégez d'abord, rejoignez plus tard.

En devinant les détails manquants, cette requête vous donnerait le nombre exact, combien de fois chaque utilisateur a été référencé dans table1 et table2 respectivement pour tous les utilisateurs :

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);

En particulier, évitez que plusieurs relations 1-n ne se multiplient lorsqu'elles sont jointes :

Pour récupérer un seul ou quelques utilisateurs uniquement, LATERAL les jointures seront plus rapides (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;

Expliquez la différence perçue

La non-concordance particulière que vous signalez est due aux spécificités d'un FULL OUTER JOIN :

Ainsi, vous obtenez des valeurs NULL ajoutées de l'autre côté pour les correspondances manquantes. count() ne compte pas les valeurs NULL. Vous pouvez donc obtenir un résultat différent selon que vous filtrez sur u1.id=100 ou u2.id=100 .

C'est juste pour expliquer, vous n'avez pas besoin d'un FULL JOIN ici. Utilisez plutôt les alternatives présentées.