Perché questo Full Outer Join non funziona?


10

Ho usato Full Outer Joins in precedenza per ottenere i risultati desiderati, ma forse non capisco perfettamente il concetto perché non sono in grado di realizzare quello che dovrebbe essere un semplice join.

Ho 2 tabelle (che chiamerò t1 e t2) con 2 campi ciascuno:

t1

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

t2

Policy_Number   Loss
101              5
103              9
107              20

Quello che sto cercando di fare è ottenere la somma di Premium e Sum of Losses da entrambe le tabelle e anche da Policy_Number. Il codice che sto usando è:

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

Il codice sopra restituirà i totali della somma corretta ma raggrupperà tutti i record in cui non esiste una corrispondenza policy_number in "NULL" policy_number.

Vorrei che il mio risultato fosse così

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

eccetera.....

Non voglio un risultato che mostri un NULL policy_number come mostrato di seguito (poiché non esiste un NULL policy_number. Questo è solo il totale per quando policy_number da entrambe le tabelle non corrisponde):

Policy_Number    Prem_Sum   Loss_Sum
   NULL            35         NULL

Se seleziono e raggruppo per t2.policy_number invece di t1.policy_number allora ottengo qualcosa come sotto come record.

Policy_Number    Prem_Sum   Loss_Sum
   NULL            NULL         20

Ancora una volta, non mi dispiace vedere NULL in Prem_Sum o in Loss_sum ma non voglio un NULL in Policy_Number. Vorrei che i miei risultati fossero qualcosa del genere

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

ect .....

Ho pensato che l'intero join esterno avrebbe raggiunto questo obiettivo, ma credo che mi manchi qualcosa. Pensavo che forse avrei potuto selezionare e raggruppare sia t1.policy_number che t2.policy_number come una query secondaria e quindi forse fare un CASO nella query esterna o qualcosa del genere ??? Non penso che dovrebbe essere così complicato.

Qualche idea o consiglio?

Risposte:


8

Dovresti fare un isnull su entrambi i poliambulatori in modo da poter raggruppare correttamente.

Poiché è un join esterno, esiste la possibilità che un lato del join sia NULL pur continuando a disporre di dati.

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)

... il che significa che i null sono trattati come valori da SQL, motivo per cui è necessario ISNULL (). Questo è il motivo per cui SQL ha una bocca così brutta. Eppure lo uso ancora quotidianamente.
Paul-Sebastian Manole,

4

Il join esterno completo creerà la struttura record di cui hai bisogno, ma non inserirà il numero 107 nella tabella 1 per te.

Penso che ciò di cui hai bisogno sia qualcosa del genere

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

Per fornire ulteriori informazioni sul motivo per cui la tua specifica query non ha funzionato. Il tuo codice di partenza era:

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 

A prima vista, sembra che dovrebbe funzionare. Tuttavia, si noti che la terza colonna specificata è t1.policynumber. Questa è anche l'unica colonna di raggruppamento. A causa di questo SQL Server vede solo i valori in t1, lasciando tutti i valori non in t1 come null (perché, ricorda, questo è un join esterno completo). Il codice isnull (t1.policynumber, t2.policynumber) fornirà tutti i valori non nulli in t1, quindi utilizzerà i valori in t2.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.