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

Lignes en double SQL avec plusieurs jointures à gauche

Vous rencontrez une diffusion agrégée dans la requête ci-dessus.

Cela se produit parce qu'il y a

  • soit une jointure 1-1 ou 1-N entre aaa &bbb
  • il y a une jointure 1-N entre bbb &ccc

Cette dernière jointure crée M doublons pour les lignes qui existent dans bbb s'ils sont joints à M lignes via la jointure à ccc

Pour corriger l'erreur, divisez la requête en deux CTE et joignez le résultat.

WITH agg_bb AS (
SELECT aa.id, sum(bb.count)
FROM aaaa aa
LEFT JOIN bbbb bb ON bb.aa_id = aa.id
GROUP BY aa.id
)
, agg_cc AS (SELECT aa.id, count(DISTINCT cc.id)
FROM aaaa aa
LEFT JOIN bbbb bb ON bb.aa_id = aa.id
LEFT JOIN cccc cc ON cc.bb_id = bb.id
GROUP BY aa.id
)
SELECT * FROM agg_bb JOIN agg_cc USING (id)

En général, pour éviter les sorts, appliquez uniquement les opérations d'agrégation aux colonnes de la relation la plus à droite dans une série de jointures. Si vous constatez que vous agrégez des colonnes à partir des tables du milieu, divisez la requête comme je l'ai fait ci-dessus. Seules les fonctions suivantes sont invariantes sur une distribution :COUNT DISTINCT , MIN , MAX