Bu beyan yasaldır (başka bir deyişle hayır FROM
gerekli değildir):
SELECT x = 1;
SELECT x = 1 WHERE 1 = 1; -- also try WHERE 1 = 0;
İşin püf noktası, açıkça var olmayan bir sütun adı girdiğiniz zamandır. Yani bunlar başarısız:
SELECT name WHERE 1 = 1;
SELECT x = 1 WHERE id > 0;
Msg 207, Seviye 16, Durum 1
Geçersiz sütun adı 'ad'.
Msg 207, Seviye 16, Durum 1
Geçersiz sütun adı 'id'.
Ancak, geçersiz sütun bir alt sorgu gibi bir şeyde tanıtıldığında, SQL Server'ın bu sorguyu alt sorgunun iç kapsamında bulamadığında yaptığı şey, bir dış kapsama çapraz olur ve alt sorguyu bu dış kapsamla ilişkili hale getirir. Bu, tüm satırları döndürür, örneğin:
SELECT * FROM sys.columns WHERE name IN (SELECT name WHERE 1 = 1);
Çünkü aslında şöyle diyor:
SELECT * FROM sys.columns WHERE name IN (SELECT sys.columns.name WHERE 1 = 1); /*
^^^^^^^^^^^ -----------
| |
----------------------------------- */
WHERE
Alt sorguda bir maddeye bile ihtiyacınız yoktur :
SELECT * FROM sys.columns WHERE name IN (SELECT name);
Gerçekten dış kapsamdaki tabloya baktığını görebilirsiniz, çünkü bu:
SELECT * FROM sys.columns WHERE name IN (SELECT name WHERE name > N'x');
Çok daha az satır döndürür (sistemimde 11).
Bu kapsam belirleme konusundaki standarda bağlı kalmayı içerir. İki #temp tablonuz olduğunda da benzer şeyler görebilirsiniz:
CREATE TABLE #foo(foo int);
CREATE TABLE #bar(bar int);
SELECT foo FROM #foo WHERE foo IN (SELECT foo FROM #bar);
Hiçbir olduğundan Açıkçası, bu doğru, hata gerektiğini foo
de #bar
? Hayır! Ne oluyor SQL Server diyor ki, "ah, foo
burada bir tane bulamadım , diğeri demek zorundasın."
Ayrıca, genel olarak, kaçınırdım NOT IN
. NOT EXISTS
bazı senaryolarda daha verimli olma potansiyeline sahiptir, ancak daha da önemlisi, hedef sütunun olması mümkün olduğunda davranışı değişmez NULL
. Daha fazla bilgi için bu gönderiye bakın .