Mengapa Gabung Luar Penuh ini tidak berfungsi?

10

Saya telah menggunakan Full Outer Joins sebelumnya untuk mendapatkan hasil yang saya inginkan, tetapi mungkin saya tidak sepenuhnya memahami konsep ini karena saya tidak dapat mencapai apa yang seharusnya menjadi join sederhana.

Saya memiliki 2 tabel (yang saya sebut t1 dan t2) dengan masing-masing 2 bidang:

t1

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

t2

Policy_Number   Loss
101              5
103              9
107              20

Apa yang saya coba lakukan adalah mendapatkan jumlah Premium dan Jumlah Kerugian dari kedua tabel dan juga Policy_Number. Kode yang saya gunakan adalah:

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

Kode di atas akan mengembalikan jumlah total yang benar tetapi akan mengelompokkan semua catatan di mana tidak ada kecocokan dengan policy_number di bawah "NULL" policy_number.

Saya ingin hasil saya terlihat seperti ini

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

dll .....

Saya tidak ingin hasil yang menunjukkan NULL policy_number seperti yang ditunjukkan di bawah ini (karena tidak ada yang namanya NULL policy_number. Ini hanya total ketika ketika policy_number dari kedua tabel tidak cocok):

Policy_Number    Prem_Sum   Loss_Sum
   NULL            35         NULL

Jika saya Memilih dan mengelompokkan berdasarkan t2.policy_number bukan t1.policy_number maka saya mendapatkan sesuatu seperti di bawah ini sebagai catatan.

Policy_Number    Prem_Sum   Loss_Sum
   NULL            NULL         20

Sekali lagi, saya tidak keberatan melihat NULL di bawah Prem_Sum atau di bawah Loss_sum tapi saya tidak ingin NULL di bawah Policy_Number. Saya ingin hasil saya seperti

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

dll .....

Saya pikir gabungan terluar penuh akan mencapai ini, tetapi saya kira saya kehilangan sesuatu. Saya berpikir mungkin saya bisa memilih dan mengelompokkan berdasarkan t1.policy_number dan t2.policy_number sebagai sub kueri dan kemudian mungkin melakukan KASUS dalam kueri luar atau sesuatu ??? Saya tidak berpikir itu harus serumit ini.

Ada ide atau saran?

Juan Velez
sumber

Jawaban:

8

Anda harus melakukan isnull pada kedua polisi sehingga Anda dapat mengelompokkan dengan benar.

Karena ini merupakan join luar, ada kemungkinan satu sisi join menjadi NULL sambil masih memiliki data.

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)
Derek Kromm
sumber
... yang berarti bahwa nulls diperlakukan seperti nilai oleh SQL yang mengapa Anda memerlukan ISNULL (). Inilah sebabnya mengapa SQL bermulut buruk. Namun saya masih menggunakannya setiap hari.
Paul-Sebastian Manole
4

Gabungan luar penuh akan membuat struktur rekaman yang Anda butuhkan, tetapi itu tidak akan memasukkan nomor kebijakan 107 ke dalam Tabel 1 untuk Anda.

Saya pikir apa yang Anda butuhkan adalah sesuatu di sepanjang garis

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)
Anak nakal
sumber
2

Untuk memberikan sedikit informasi lebih lanjut mengapa kueri spesifik Anda tidak berfungsi. Kode awal Anda adalah:

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 

Pada pandangan pertama, ini sepertinya bekerja. Namun, perhatikan bahwa kolom ketiga yang ditentukan adalah t1.policynumber. Ini juga merupakan satu-satunya kolom pengelompokan. Karena SQL Server ini hanya melihat nilai dalam t1, meninggalkan nilai apa pun yang tidak dalam t1 sebagai nol (karena, ingat, ini adalah gabungan luar penuh). Kode isnull (t1.policynumber, t2.policynumber) akan memberi Anda semua nilai non-null di t1, lalu gunakan nilai di t2.

DForck42
sumber