web-dev-qa-db-fra.com

SQL Server JOIN valeurs NULL manquantes

Supposons que j'ai les 2 tables suivantes:

      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

Maintenant, je veux rejoindre ces tables sur Col1 et Col2 et ramener l'ensemble complet à ressembler à:

     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

Donc, j'ai essayé un SQL comme:

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

Mais il ne correspond pas aux valeurs NULL dans Col2, alors je me retrouve avec:

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

Comment puis-je obtenir le résultat que je recherche?

Merci!

50
John Bustos

Vous pouvez être explicite sur les jointures:

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)

En pratique, je serais plus susceptible d’utiliser coalesce() dans la condition de jointure:

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

'' serait une valeur ne figurant dans aucune des tables.

Juste un mot de prudence. Dans la plupart des bases de données, l'utilisation de l'une de ces constructions empêche l'utilisation d'index.

69
Gordon Linoff

Utilisez Jointure externe gauche au lieu de Jointure interne pour inclure des lignes avec NULLS.

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

Pour plus d'informations, voir ici: http://technet.Microsoft.com/en-us/library/ms190409(v=sql.105).aspx

23
Dave Hackett

Essayez d’utiliser la fonction ISNULL:

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

'ZZZZ' est une valeur arbitraire jamais dans la table.

15
sgeddes

Bidouille sale et rapide:

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))
8
jap1968

vous pouvez simplement cartographier comme ça

select * from tableA a
join tableB b on isnull(a.colID,'') = isnull(b.colId,'')
1
wiretext

pour une raison quelconque, je ne pouvais pas le faire fonctionner avec la jointure externe.

Alors j'ai utilisé:

SELECT * from t1 where not Id in (SELECT DISTINCT t2.id from t2)
0
user11333280