Ich versuche, zwei Tabellen zu vergleichen, um Zeilen in jeder Tabelle zu finden, die nicht in der anderen Tabelle enthalten sind. Tabelle 1 enthält eine groupby -Spalte, um zwei Datensätze innerhalb der ersten Tabelle zu erstellen.T-SQL - Linke äußere Verknüpfungen - Filtert die where-Klausel im Vergleich zur on-Klausel
groupby number
----------- -----------
1 1
1 2
2 1
2 2
2 4
Tabelle 2 hat nur eine Spalte.
number
-----------
1
3
4
Also Tabelle 1 hat die Werte 1,2,4 in Gruppe 2 und Tabelle 2 hat die Werte 1,3,4.
Ich erwarte, dass das folgende Ergebnis, wenn für die Gruppe Beitritt 2:
`Table 1 LEFT OUTER Join Table 2`
T1_Groupby T1_Number T2_Number
----------- ----------- -----------
2 2 NULL
`Table 2 LEFT OUTER Join Table 1`
T1_Groupby T1_Number T2_Number
----------- ----------- -----------
NULL NULL 3
Die einzige Art, wie ich dies an der Arbeit bekommen kann, ist, wenn ich eine where-Klausel für das erste beitreten setzen:
PRINT 'Table 1 LEFT OUTER Join Table 2, with WHERE clause'
select table1.groupby as [T1_Groupby],
table1.number as [T1_Number],
table2.number as [T2_Number]
from table1
LEFT OUTER join table2
--******************************
on table1.number = table2.number
--******************************
WHERE table1.groupby = 2
AND table2.number IS NULL
und ein Filter in der ON für die zweite:
PRINT 'Table 2 LEFT OUTER Join Table 1, with ON clause'
select table1.groupby as [T1_Groupby],
table1.number as [T1_Number],
table2.number as [T2_Number]
from table2
LEFT OUTER join table1
--******************************
on table2.number = table1.number
AND table1.groupby = 2
--******************************
WHERE table1.number IS NULL
Kann jemand mit einem Weg kommen, den Filter nicht zu verwenden in der on-Klausel, aber in der where-Klausel?
Der Kontext davon ist, ich habe einen Staging-Bereich in einer Datenbank und ich möchte neue Datensätze und Datensätze identifizieren, die gelöscht wurden. Das groupby-Feld entspricht einer Batchid für einen Extrakt, und ich vergleiche den neuesten Extrakt in einer temporären Tabelle mit dem in einer partioneds-Tabelle gespeicherten Batch von gestern, der auch alle zuvor extrahierten Batches enthält. Code erstellen Tabelle 1 und 2:
create table table1 (number int, groupby int)
create table table2 (number int)
insert into table1 (number, groupby) values (1, 1)
insert into table1 (number, groupby) values (2, 1)
insert into table1 (number, groupby) values (1, 2)
insert into table2 (number) values (1)
insert into table1 (number, groupby) values (2, 2)
insert into table2 (number) values (3)
insert into table1 (number, groupby) values (4, 2)
insert into table2 (number) values (4)
EDIT:
Ein bisschen mehr Kontext - je nachdem, wo ich legte den Filter ich unterschiedliche Ergebnisse. Wie oben erwähnt, gibt mir die Where-Klausel das korrekte Ergebnis in einem Zustand und das ON im anderen Zustand. Ich bin auf der Suche nach einem konsequenten Weg, dies zu tun.
Wo -
select table1.groupby as [T1_Groupby],
table1.number as [T1_Number],
table2.number as [T2_Number]
from table1
LEFT OUTER join table2
--******************************
on table1.number = table2.number
--******************************
WHERE table1.groupby = 2
AND table2.number IS NULL
Ergebnis:
T1_Groupby T1_Number T2_Number
----------- ----------- -----------
2 2 NULL
On -
select table1.groupby as [T1_Groupby],
table1.number as [T1_Number],
table2.number as [T2_Number]
from table1
LEFT OUTER join table2
--******************************
on table1.number = table2.number
AND table1.groupby = 2
--******************************
WHERE table2.number IS NULL
Ergebnis:
T1_Groupby T1_Number T2_Number
----------- ----------- -----------
1 1 NULL
2 2 NULL
1 2 NULL
Wo (Tabelle 2 diesmal) -
select table1.groupby as [T1_Groupby],
table1.number as [T1_Number],
table2.number as [T2_Number]
from table2
LEFT OUTER join table1
--******************************
on table2.number = table1.number
AND table1.groupby = 2
--******************************
WHERE table1.number IS NULL
Ergebnis:
T1_Groupby T1_Number T2_Number
----------- ----------- -----------
NULL NULL 3
On -
select table1.groupby as [T1_Groupby],
table1.number as [T1_Number],
table2.number as [T2_Number]
from table2
LEFT OUTER join table1
--******************************
on table2.number = table1.number
--******************************
WHERE table1.number IS NULL
AND table1.groupby = 2
Ergebnis:
T1_Groupby T1_Number T2_Number
----------- ----------- -----------
(0) rows returned
Warum ist es wichtig, die Bedingung von der 'JOIN'-Klausel in die' WHERE'-Klausel zu verschieben? Das Setzen von Prädikaten in 'JOIN' ist normal, wenn Sie diese Art von Verhalten wünschen. – Aaronaught
Das Verschieben in die where-Klausel ist nicht so wichtig wie die Tatsache, dass ich für den ersten Join, bei dem ich Tabelle 1 mit Tabelle 2 verbinde, ein anderes Ergebnis erhalte, wenn ich den Filter in on und nicht in where lege. PRINT 'Tabelle 1 LEFT OUTER JOIN Tabelle 2, mit WHERE-Klausel' \t table1.groupby als [T1_Groupby] wählen , \t \t table1.number als [T1_Number], \t \t table2.number als [T2_Number] aus \t tabelle1 \t \t LEFT OUTER JOIN table2 \t \t \t - ****************************** \t \t \t auf table1.number = table2.number \t \t \t UND table1.groupby = 2 \t \t \t - ****************************** WHERE \t --table1 .groupby = 2 UND \t table2.number IS NULL Gibt null nur –
Nun, welche wollen Sie? Es klingt wie der NULL-Join, was du meinst. Dies ist eine Standardmethode für Abfragen wie diese und ist in der Regel den Unterabfragenalternativen vorzuziehen. Ich sehe keinen Vorteil darin, die Bedingung in eine WHERE-Klausel zu schieben. – bobince