我目前面临以下问题: 我有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。
答案 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 DISTINCT
,MIN
,MAX