Rau*_*uno 8 postgresql left-join duplicates
我目前面临以下问题:我需要从中获取信息的 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
Run Code Online (Sandbox Code Playgroud)
有没有办法在没有其他查询的情况下获得正确的 bb.count 总和?我删除第二个左连接的那一刻一切都很好,不幸的是我需要它作为第三个返回值,并且我无法将它们分组而不导致结果重复(排序)行。
可以说有
bb1.count = 9
bb2.count = 5
Run Code Online (Sandbox Code Playgroud)
有 2 行,cc.bb_id = bb1.id
我得到的结果是 23 而不是 14。
Hal*_*Ali 11
您在上述查询中遇到了聚合扇出。
发生这种情况是因为有
aaa&之间的 1-1 或 1-N 连接bbbbbb&之间有一个 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)
Run Code Online (Sandbox Code Playgroud)
一般来说,为了避免扇出,只对一系列连接中最右边关系的列应用聚合操作。如果您发现您正在聚合中间表中的列,请像我上面所做的那样拆分查询。只有以下函数在扇出中是不变的:COUNT DISTINCT, MIN,MAX
| 归档时间: |
|
| 查看次数: |
4820 次 |
| 最近记录: |