Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

NOT IN (sous-requête) produisant zéro ligne

Si b est nullable, ce n'est pas un bogue. Le problème est que SQL Server transforme NOT IN en une série de <> 1 AND <> 2 AND <> 3 etc. Si vous avez <> NULL , qui renvoie inconnu, ce qui dans ce cas signifie faux. Dans différents scénarios, cela peut qualifier ou disqualifier TOUS Lignes. Plutôt que le LEFT JOIN approche, vous devriez dire :

FROM dbo.OuterTable AS t
WHERE NOT EXISTS (SELECT 1 FROM x WHERE b = t.a);

Voici une démonstration rapide :

DECLARE @x TABLE(i INT);
INSERT @x VALUES(1),(2);

DECLARE @y TABLE(j INT);
INSERT @y VALUES(2),(NULL);

SELECT i FROM @x WHERE i NOT IN -- produces zero results
  (SELECT j FROM @y);

SELECT i FROM @x  AS x WHERE NOT EXISTS -- produces one result
  (SELECT 1 FROM @y WHERE j = x.i);

Pour plus de détails (et des mesures pour prouver pourquoi NOT EXISTS est la meilleure alternative) :

http://www.sqlperformance.com /2012/12/t-sql-queries/left-anti-semi-join

Veuillez également lire cet article de blog de Gail Shaw :

http://sqlinthewild. co.za/index.php/2010/02/18/not-exists-vs-not-in/