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.