具有多个左连接的SQL重复行

时间:2017-09-18 12:16:13

标签: postgresql duplicates left-join

我目前面临以下问题:   我有3个表我需要信息,这两个连接都是一对多的。由于某种原因,第二次连接会创建行的重复,因此第二个返回值会混乱(bb.count乘以第二个连接行的数量)

SELECT aa.id, sum(bb.count), 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

有没有办法在没有其他查询的情况下获得bb.count的正确总和? 我删除第二个左边的那一刻加入一切都很好,不幸的是我需要它作为第三个返回值,我不能将它们分组而不会导致结果中出现重复(排序)行。

让我们说

bb1.count = 9
bb2.count = 5

有两行cc.bb_id = bb1.id 我得到的结果是23而不是14。

1 个答案:

答案 0 :(得分:4)

您在上述查询中遇到了聚合扇出。

这是因为有

  • aaa&之间的1-1或1-N连接bbb
  • bbb&之间有一个1-N联接ccc

后者联接为M中存在的行创建bbb重复项,如果它们通过联接加入M行,则ccc

要修复错误,请将查询拆分为两个CTE&加入结果。

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)

通常,为了避免扇出,只在一系列连接中将聚合操作应用于最右边关系的列。如果您发现正在汇总中间表中的列,请按照上面的步骤拆分查询。粉丝输出中只有以下功能不变:COUNT DISTINCTMINMAX