2017-09-18 18 views
0

私は現在、次の問題に直面しています: 私は情報が必要な3つのテーブルがあり、これらの結合は両方とも1対多です。いくつかの理由が第二の参加のための列の複製を作成し、その結果第2の戻り値が台無しになるにつれて複数の左結合を持つ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? 2番目の左のジョインをすべて削除した瞬間、残念ながら3番目の戻り値が必要なので、結果で重複する(並べ替え)結果を出さずにグループ化することはできません。

bb1.count = 9 
bb2.count = 5 

がありますと言うと私が得るcc.bb_id = bb1.id 結果は、あなたが上記のクエリで集計ファンアウトを経験している代わりに、14

+0

最小作業サンプル? –

答えて

2

の23で2行がありますできます。

  • 1-1または1-N bbb & ccc

間の1-Nの参加がある

  • bbb & aaa間の結合のいずれかであるので、これが発生後者の結合は、の複製を bbbに存在する行に対して、それらがM行に結合してに結合した場合に作成します

    エラーを修正するには、クエリを2つの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

    +0

    ありがとう、ちょうど私の一日を保存しました! – Rauno

    関連する問題