2017-09-18 43 views
0

我目前正面臨以下問題: 我有3個表,我需要信息,而且這兩個聯接都是一對多的。出於某種原因,第二個連接創建行的重複,因此第二返回值被搞砸具有多個左連接的SQL重複行

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得到通過的第二個連接行金額乘以) bb.count沒有另一個查詢? 當我刪除第二個左加入一切都很好,不幸的是我需要它的第三個返回值,我不能將它們分組,而不會導致結果中的重複(排序)行。

比方說有

bb1.count = 9 
bb2.count = 5 

而且有2行,其中cc.bb_id = bb1.id 結果我得到的是23,而不是14

+0

最小工作示例.. –

回答

2

您遇到聚集扇出在上面的查詢。

這是因爲有

  • 無論是1-1或1-N aaa & bbb
  • 之間加入有一個1-N聯接bbb之間& ccc

的後者聯接爲bbb中存在的行創建M重複項,如果它們通過聯接連接到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

+0

謝謝你,你剛纔救了我的天! – Rauno