ทำไม Full Outer Join นี้ไม่ทำงาน?


10

ฉันเคยใช้ Full Outer Joins มาก่อนเพื่อให้ได้ผลลัพธ์ที่ต้องการ แต่บางทีฉันอาจไม่เข้าใจแนวคิดอย่างเต็มที่เพราะฉันไม่สามารถบรรลุสิ่งที่ควรเข้าร่วมอย่างง่าย

ฉันมี 2 ตาราง (ซึ่งฉันจะเรียก t1 และ t2) โดยมี 2 ฟิลด์แต่ละฟิลด์:

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 รหัสที่ฉันใช้คือ:

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

ถ้าฉันเลือกและจัดกลุ่มตาม t2.policy_number แทนที่จะเป็น t1.policy_number ฉันจะได้สิ่งที่ต้องการด้านล่างเป็นบันทึก

Policy_Number    Prem_Sum   Loss_Sum
   NULL            NULL         20

อีกครั้งฉันไม่รังเกียจที่จะเห็น NULL ภายใต้ Prem_Sum หรือภายใต้ Loss_sum แต่ฉันไม่ต้องการ NULL ภายใต้ Policy_Number ฉันต้องการให้ผลลัพธ์ของฉันเป็นสิ่งที่ต้องการ

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

ฯลฯ.....

ฉันคิดว่าการเข้าร่วมด้านนอกเต็มรูปแบบจะทำได้ แต่ฉันคิดว่าฉันขาดอะไรไป ฉันคิดว่าบางทีฉันสามารถเลือกและจัดกลุ่มโดยทั้ง t1.policy_number และ t2.policy_number เป็นแบบสอบถามย่อยและจากนั้นอาจทำ CASE ในแบบสอบถามภายนอกหรืออะไรก็ได้ ??? ฉันไม่คิดว่ามันจะซับซ้อนขนาดนี้

ความคิดหรือคำแนะนำใด ๆ

คำตอบ:


8

คุณควรทำ isnull ทั้งสอง policynumbers เพื่อให้คุณสามารถจัดกลุ่มได้อย่างถูกต้อง

เนื่องจากเป็นการเข้าร่วมด้านนอกจึงมีความเป็นไปได้ด้านหนึ่งของการเข้าร่วมเป็น 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 ถึงพูดไม่ดี แต่ฉันก็ยังใช้มันทุกวัน
พอล - เซบาสเตียน 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 

ได้อย่างรวดเร็วก่อนดูเหมือนว่ามันควรจะทำงาน อย่างไรก็ตามโปรดสังเกตว่าคอลัมน์ที่สามที่ระบุไว้คือ t1.policynumber นี่เป็นคอลัมน์การจัดกลุ่ม แต่เพียงผู้เดียว เนื่องจาก SQL Server นี้เห็นเฉพาะค่าใน t1 เท่านั้นปล่อยให้ค่าใด ๆ ที่ไม่อยู่ใน t1 เป็นค่าว่าง (เพราะจำไว้ว่านี่เป็นการรวมภายนอกเต็มรูปแบบ) รหัส isnull (t1.policynumber, t2.policynumber) จะให้ค่าที่ไม่เป็นโมฆะทั้งหมดใน t1 จากนั้นใช้ค่าใน t2

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.