web-dev-qa-db-ja.com

この完全外部結合が機能しないのはなぜですか?

以前は完全な外部結合を使用して希望の結果を得ていましたが、単純な結合を実現できないため、概念を完全に理解できていない可能性があります。

それぞれ2つのフィールドを持つ2つのテーブル(t1とt2と呼びます)があります。

t1

Policy_Number Premium
101             15
102              7
103             10
108             25
111              3

t2

Policy_Number   Loss
101              5
103              9
107              20

私がやろうとしていることは、両方のテーブルとPolicy_NumberからPremiumとSum of Lossesの合計を取得することです。私が使用しているコードは:

select sum(premium) Prem_Sum, sum(Loss) Loss_Sum, t1.policynumber
from t1 full outer join t2 on t1.policynumber = t2.policynumber
group by t1.policynumber

上記のコードは正しい合計を返しますが、一致するpolicy_numberがないすべてのレコードを「NULL」policy_numberでグループ化します。

結果がこのように見えるようにしたい

Policy_Number    Prem_Sum    Loss_Sum
    107            NULL        20
    111              3        NULL
    101             15          5

等.....

以下に示すように、NULLのpolicy_numberを示す結果は必要ありません(NULLのpolicy_numberは存在しないためです。これは、両方のテーブルのpolicy_numberが一致しない場合の合計です)。

Policy_Number    Prem_Sum   Loss_Sum
   NULL            35         NULL

T1.policy_numberの代わりにt2.policy_numberでグループ化すると、以下のようなレコードが表示されます。

Policy_Number    Prem_Sum   Loss_Sum
   NULL            NULL         20

繰り返しますが、Prem_SumまたはLoss_sumの下にNULLが表示されてもかまいませんが、Policy_Numberの下にNULLが必要ではありません。結果が次のようなものになるようにしたい

Policy_Number    Prem_Sum    Loss_Sum
    107            NULL        20
    111              3        NULL
    101             15          5

ect .....

完全な外部結合でこれを達成できると思っていましたが、何かが足りないようです。私は多分t1.policy_numberとt2.policy_numberの両方をサブクエリとして選択してグループ化し、外側のクエリまたは何かでCASEを実行できると思いましたか???こんなに複雑だとは思わない。

アイデアやアドバイスはありますか?

10
Juan Velez

適切にグループ化できるように、両方のポリシー番号でisnullを実行する必要があります。

これは外部結合であるため、データを保持したまま、結合の片側がNULLになる可能性があります。

select sum(premium) Prem_Sum, sum(Loss) Loss_Sum, isnull(t1.policynumber, t2.policynumber)
from t1 full outer join t2 on t1.policynumber = t2.policynumber
group by isnull(t1.policynumber, t2.policynumber)
8
Derek Kromm

完全外部結合は必要なレコード構造を作成しますが、ポリシー番号107を表1に追加しません。

必要なのは、

select coalesce(t1.policy_number, t2.policy_number) as PolicyNumber, 
sum(t1.premium) as PremSum, sum(t2.loss) as LossSum
from t1 full outer join t2 on t1.policy_number = t2.policy_number
group by coalesce(t1.policy_number, t2.policy_number)
4
Hellion

特定のクエリが機能しなかった理由についてもう少し情報を提供するため。あなたの開始コードは:

select sum(premium) Prem_Sum, sum(Loss) Loss_Sum, t1.policynumber 
from t1 full outer join t2 on t1.policynumber = t2.policynumber 
group by t1.policynumber 

一見すると、これは機能するはずです。ただし、指定された3番目の列はt1.policynumberであることに注意してください。これも唯一のグループ化カラムです。このため、SQL Serverはt1の値のみを認識し、t1にない値はすべてnullとして残します(これは完全外部結合であるため、覚えておいてください)。 isnull(t1.policynumber、t2.policynumber)コードは、t1にすべての非null値を提供し、次にt2に値を使用します。

2
DForck42