Cette déclaration est légale (en d'autres termes, aucune FROMn'est requise):
SELECT x = 1;
SELECT x = 1 WHERE 1 = 1; -- also try WHERE 1 = 0;
L'astuce consiste à introduire un nom de colonne qui ne peut clairement pas exister. Donc, ceux-ci échouent:
SELECT name WHERE 1 = 1;
SELECT x = 1 WHERE id > 0;
Msg 207, niveau 16, état 1
Nom de colonne non valide 'nom'.
Msg 207, niveau 16, état 1
Nom de colonne non valide «id».
Mais lorsque la colonne non valide est introduite dans quelque chose comme une sous-requête, ce que fait SQL Server lorsqu'il ne peut pas trouver cette colonne dans la portée interne de la sous-requête, est traversé vers une portée externe et rend la sous-requête corrélée à cette portée externe. Cela renverra toutes les lignes, par exemple:
SELECT * FROM sys.columns WHERE name IN (SELECT name WHERE 1 = 1);
Parce qu'il dit essentiellement:
SELECT * FROM sys.columns WHERE name IN (SELECT sys.columns.name WHERE 1 = 1); /*
^^^^^^^^^^^ -----------
| |
----------------------------------- */
Vous n'avez même pas besoin d'une WHEREclause dans la sous-requête:
SELECT * FROM sys.columns WHERE name IN (SELECT name);
Vous pouvez voir qu'il regarde vraiment la table de portée externe, car ceci:
SELECT * FROM sys.columns WHERE name IN (SELECT name WHERE name > N'x');
Renvoie beaucoup moins de lignes (11 sur mon système).
Cela implique le respect de la norme sur la portée. Vous pouvez voir des choses similaires lorsque vous avez deux tables #temp:
CREATE TABLE #foo(foo int);
CREATE TABLE #bar(bar int);
SELECT foo FROM #foo WHERE foo IN (SELECT foo FROM #bar);
De toute évidence, cela devrait être une erreur, non, car il n'y a pas d' fooentrée #bar? Nan. Ce qui se passe, c'est que SQL Server dit: "oh, je n'ai pas trouvé un fooici, vous devez avoir voulu dire l'autre."
Aussi, en général, j'éviterais NOT IN. NOT EXISTSa le potentiel d'être plus efficace dans certains scénarios, mais plus important encore, son comportement ne change pas lorsqu'il est possible que la colonne cible puisse l'être NULL. Voir cet article pour plus d'informations .