Warum funktioniert dieser vollständige äußere Join nicht?

10

Ich habe zuvor vollständige äußere Verknüpfungen verwendet, um die gewünschten Ergebnisse zu erzielen, aber möglicherweise verstehe ich das Konzept nicht vollständig, da ich nicht in der Lage bin, eine einfache Verknüpfung zu erreichen.

Ich habe 2 Tabellen (die ich t1 und t2 nenne) mit jeweils 2 Feldern:

t1

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

t2

Policy_Number   Loss
101              5
103              9
107              20

Ich versuche, die Summe aus Premium und Summe der Verluste aus beiden Tabellen und auch aus der Policy_Number zu erhalten. Der Code, den ich benutze, ist:

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

Der obige Code gibt die korrekten Summensummen zurück, gruppiert jedoch alle Datensätze, bei denen keine Übereinstimmung mit policy_number vorliegt, unter "NULL" policy_number.

Ich möchte, dass mein Ergebnis so aussieht

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

etc.....

Ich möchte kein Ergebnis, das eine NULL-Richtliniennummer wie unten gezeigt anzeigt (da es keine NULL-Richtliniennummer gibt. Dies ist nur die Summe, wenn die Richtliniennummer aus beiden Tabellen nicht übereinstimmt):

Policy_Number    Prem_Sum   Loss_Sum
   NULL            35         NULL

Wenn ich nach t2.policy_number anstelle von t1.policy_number auswähle und gruppiere, erhalte ich als Datensatz Folgendes.

Policy_Number    Prem_Sum   Loss_Sum
   NULL            NULL         20

Auch hier macht es mir nichts aus, NULL unter Prem_Sum oder unter Loss_sum zu sehen, aber ich möchte kein NULL unter Policy_Number. Ich möchte, dass meine Ergebnisse so etwas wie sind

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

ect .....

Ich dachte, die vollständige äußere Verbindung würde dies erreichen, aber ich denke, mir fehlt etwas. Ich dachte, ich könnte vielleicht sowohl t1.policy_number als auch t2.policy_number als Unterabfrage auswählen und gruppieren und dann vielleicht einen CASE in der äußeren Abfrage machen oder so ??? Ich denke nicht, dass es so kompliziert sein sollte.

Irgendwelche Ideen oder Ratschläge?

Juan Velez
quelle

Antworten:

8

Sie sollten für beide Richtliniennummern einen isnull ausführen, damit Sie richtig gruppieren können.

Da es sich um einen Outer-Join handelt, besteht die Möglichkeit, dass eine Seite des Joins NULL ist, während noch Daten vorhanden sind.

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
quelle
... was bedeutet, dass Nullen von SQL wie Werte behandelt werden, weshalb Sie ISNULL () benötigen. Aus diesem Grund hat SQL einen so schlechten Mund. Trotzdem benutze ich es immer noch täglich.
Paul-Sebastian Manole
4

Durch die vollständige äußere Verknüpfung wird die von Ihnen benötigte Datensatzstruktur erstellt, die Richtliniennummer 107 wird jedoch nicht für Sie in Tabelle 1 aufgeführt.

Ich denke, was Sie brauchen, ist etwas in der Art von

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)
Hellion
quelle
2

Um ein wenig mehr Informationen darüber zu geben, warum Ihre spezifische Abfrage nicht funktioniert hat. Ihr Startcode war:

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 

Auf den ersten Blick sieht es so aus, als ob es funktionieren sollte. Beachten Sie jedoch, dass die dritte angegebene Spalte t1.policynumber ist. Dies ist auch die einzige Gruppierungsspalte. Aus diesem Grund sieht SQL Server nur die Werte in t1, wobei alle Werte, die nicht in t1 enthalten sind, als Null belassen werden (da dies ein vollständiger äußerer Join ist). Der isnull-Code (t1.policynumber, t2.policynumber) liefert Ihnen alle Nicht-Null-Werte in t1 und verwendet dann Werte in t2.

DForck42
quelle