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


10

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

それぞれ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を実行できると思いましたか??? こんなに複雑だとは思いません。

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

回答:


8

適切にグループ化できるように、両方のポリシー番号で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)

...つまり、NULLはSQLによって値のように扱われるため、ISNULL()が必要です。これが、SQLが非常に悪口である理由です。それでも私はそれを毎日使っています。
Paul-Sebastian Manole

4

完全外部結合は必要なレコード構造を作成しますが、ポリシー番号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)

2

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

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に値を使用します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.