2013-01-16 8 views
32

Załóżmy miałem następujące 2 tabele:SQL Server JOIN brakuje NULL wartości

 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 

Teraz chcę dołączyć do tych tabel na Col1 i Col2 i przywrócić cały zestaw wyglądać:

 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 

Więc starałem się jak SQL:

SELECT Table1.Col1, Table1.Col2, Table1.Col3, Table2.Col4 
FROM Table1 INNER JOIN Table2 
ON Table1.Col1 = Table2.Col1 
AND Table1.Col2 = Table2.Col2 

Ale to nie jest dopasowanie th e NULL wartości w Col2, więc skończyć z:

 Result: 
Col1:  Col2:  Col3:  Col4: 
a   b   c   d 
h   i   j   k 

Jak mogę uzyskać wynik szukam ??

Dzięki!

Odpowiedz

45

Możesz być jawne o dołącza:

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) 

W praktyce, byłbym bardziej skłonni do korzystania coalesce() w stanie dołączyć:

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, '')) 

Gdzie '' byłaby wartość nie którykolwiek z tabel.

Tylko słowo ostrożności. W większości baz danych użycie dowolnej z tych konstrukcji uniemożliwia korzystanie z indeksów.

+1

Hi @ Gordon-linoff, odpowiedź była najcenniejsza w tym przypadku. Wielkie dzięki –

10

Spróbuj użyć ISNULL funkcję:

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') 

Gdzie 'ZZZZ' jest jakąś dowolną wartość nigdy w tabeli.

+5

Wprowadza magiczne wartości, których unikam, chyba że absolutnie konieczne. –

+0

To działałoby ładnie, ale zakłada, że ​​'0' nie jest używane gdzie indziej w innym wierszu. – PinnyM

+0

Tak, wolę odpowiedź od Gordona, po prostu oferuję alternatywę. I prawdopodobnie użyłbym innej wartości, o której wiedziałem, że nie może być reprezentowana w zwracanych wartościach, takich jak "ZZZZ" czy coś takiego :-) – sgeddes

5

Brudny i szybkie 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)) 
+0

Dzięki, @Jap - Dokładnie tego, czego szukałem ... Gordon pobił cię do tego , ale dzięki za odpowiedź! –

16

Użyj lewej Zewnętrzne Dołącz zamiast wewnętrznej Dołącz zawierać wiersze z wartości null.

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 

Aby uzyskać więcej informacji, zobacz tutaj: http://technet.microsoft.com/en-us/library/ms190409(v=sql.105).aspx

+0

Działa dla mnie. Łatwy i czysty. – Kuvalya

+0

To nie odpowiada na oryginalne pytanie. twoje rozwiązanie będzie zawierać puste wiersze dla tabeli 2, jeśli nie zostanie znalezione dopasowanie. spójrz na drugi rząd w obu tabelach w pytaniu OP – AaA

+0

działa dla mnie..dzięki! –

-1

można po prostu map jak ten

select * from tableA a 
join tableB b on isnull(a.colID,'') = isnull(b.colId,'') 
Powiązane problemy