Angenommen, ich hätte die folgenden 2 Tabellen:
Table1: Table2:
Col1: Col2: Col3: Col1: Col2: Col4:
a b c a b d
e <null> f e <null> g
h i j h i k
l <null> m l <null> n
o <null> p o <null> q
Jetzt möchte ich diese Tabellen verbinden Col1
und Col2
das gesamte Set so zurückbringen, dass es so aussieht:
Result:
Col1: Col2: Col3: Col4:
a b c d
e <null> f g
h i j k
l <null> m n
o <null> p q
Also habe ich ein SQL wie folgt ausprobiert:
SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4
FROM Table1 INNER JOIN Table2
ON Table1.Col1 = Table2.Col1
AND Table1.Col2 = Table2.Col2
Aber es stimmt nicht mit den NULL
Werten in überein Col2
, so dass ich am Ende Folgendes habe:
Result:
Col1: Col2: Col3: Col4:
a b c d
h i j k
Wie kann ich das gewünschte Ergebnis erzielen?
Vielen Dank!
sql
sql-server
John Bustos
quelle
quelle
Antworten:
Sie können die Verknüpfungen explizit angeben:
SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 FROM Table1 INNER JOIN Table2 ON (Table1.Col1 = Table2.Col1 or Table1.Col1 is NULL and Table2.Col1 is NULL) AND (Table1.Col2 = Table2.Col2 or Table1.Col2 is NULL and Table2.Col2 is NULL)
In der Praxis würde ich eher
coalesce()
die Join-Bedingung verwenden:SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 FROM Table1 INNER JOIN Table2 ON (coalesce(Table1.Col1, '') = coalesce(Table2.Col1, '')) AND (coalesce(Table1.Col2, '') = coalesce(Table2.Col2, ''))
Wo
''
wäre ein Wert nicht in einer der Tabellen.Nur ein Wort der Vorsicht. In den meisten Datenbanken verhindert die Verwendung eines dieser Konstrukte die Verwendung von Indizes.
quelle
ON (T1.C1=T2.C1 or (coalesce(T1.C1,T2.C1) is null)) and (T1.C2=T2.C2 or (coalesce(T1.C2,T2.C2) is null))
Table1=(a,b,c)(a,null,d) Table2=(a,b,e)
. In diesem Fall stimmt der Join mit dem FallTable1(a,null,d)
mit dem nicht vorhandenen Fall übereinTable2(a,null,null)
. Dies sollte nicht zu einer Übereinstimmung führen.NULL
inTable2.Col2
denen es Übereinstimmungen gibt, und Fällen, in denen überhaupt keine Aufzeichnungen vorliegenTable2
.Verwenden Sie Left Outer Join anstelle von Inner Join, um Zeilen mit NULLS einzuschließen.
SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 FROM Table1 LEFT OUTER JOIN Table2 ON Table1.Col1 = Table2.Col1 AND Table1.Col2 = Table2.Col2
Weitere Informationen finden Sie hier: http://technet.microsoft.com/en-us/library/ms190409(v=sql.105).aspx
quelle
Versuchen Sie es mit der
ISNULL
Funktion:SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 FROM Table1 INNER JOIN Table2 ON Table1.Col1 = Table2.Col1 AND ISNULL(Table1.Col2, 'ZZZZ') = ISNULL(Table2.Col2,'ZZZZ')
Wo
'ZZZZ'
ist ein beliebiger Wert nie in der Tabelle.quelle
Table2.Col2 IS NULL
denen kein übereinstimmender Datensatz vorhanden istTable2
.Schmutziger und schneller Hack:
SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 FROM Table1 INNER JOIN Table2 ON Table1.Col1 = Table2.Col1 AND ((Table1.Col2 = Table2.Col2) OR (Table1.Col2 IS NULL AND Table2.Col2 IS NULL))
quelle
Sie können einfach so abbilden
select * from tableA a join tableB b on isnull(a.colID,'') = isnull(b.colId,'')
quelle
Aus irgendeinem Grund konnte ich es nicht dazu bringen, mit dem äußeren Join zu arbeiten.
Also habe ich verwendet:
SELECT * from t1 where not Id in (SELECT DISTINCT t2.id from t2)
quelle
Die einzig richtige Antwort besteht darin, keine Spalten mit Nullwerten zu verbinden. Dies kann sehr schnell zu unerwünschtem Verhalten führen.
zB isnull (b.colId, ''): Was passiert, wenn Ihre Daten leere Zeichenfolgen enthalten? Der Join kann doppelte Zeilen enthalten, was in diesem Fall vermutlich nicht beabsichtigt ist.
quelle
Versuchen Sie, eine zusätzliche Bedingung in join zu verwenden:
SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 FROM Table1 INNER JOIN Table2 ON (Table1.Col1 = Table2.Col1 OR (Table1.Col1 IS NULL AND Table2.Col1 IS NULL) )
quelle