이 진술은 합법적입니다 (즉, FROM
필요 하지 않습니다).
SELECT x = 1;
SELECT x = 1 WHERE 1 = 1; -- also try WHERE 1 = 0;
요점은 명확하게 존재할 수없는 열 이름을 도입 할 때입니다. 그래서 이것들은 실패합니다 :
SELECT name WHERE 1 = 1;
SELECT x = 1 WHERE id > 0;
메시지 207, 수준 16, 상태 1
잘못된 열 이름 'name'입니다.
메시지 207, 수준 16, 상태 1
잘못된 열 이름 'id'입니다.
그러나 잘못된 쿼리가 하위 쿼리와 같은 방식으로 도입되면 하위 쿼리의 내부 범위에서 해당 열을 찾을 수 없을 때 SQL Server가 수행하는 작업은 외부 범위로 이동하고 하위 쿼리가 해당 외부 범위와 상관됩니다. 예를 들어 모든 행을 반환합니다.
SELECT * FROM sys.columns WHERE name IN (SELECT name WHERE 1 = 1);
본질적으로 다음과 같이 말합니다.
SELECT * FROM sys.columns WHERE name IN (SELECT sys.columns.name WHERE 1 = 1); /*
^^^^^^^^^^^ -----------
| |
----------------------------------- */
WHERE
하위 쿼리 에는 절이 필요하지 않습니다 .
SELECT * FROM sys.columns WHERE name IN (SELECT name);
외부 범위 테이블을 실제로보고 있음을 알 수 있습니다.
SELECT * FROM sys.columns WHERE name IN (SELECT name WHERE name > N'x');
훨씬 적은 수의 행을 반환합니다 (시스템에서 11 개).
여기에는 범위 지정에 대한 표준을 준수하는 것이 포함됩니다. 두 개의 #temp 테이블이 있으면 비슷한 것을 볼 수 있습니다.
CREATE TABLE #foo(foo int);
CREATE TABLE #bar(bar int);
SELECT foo FROM #foo WHERE foo IN (SELECT foo FROM #bar);
더 있기 때문에 분명히,이, 우, 오류가 없어야 foo
에서 #bar
? 아니. 무슨 일이 일어나는지 SQL Server는 "오, 나는 foo
여기를 찾지 못했습니다 . 당신은 다른 것을 의미했을 것입니다."라고 말합니다.
또한 일반적으로 피할 것 NOT IN
입니다. NOT EXISTS
일부 시나리오에서는 더 효율적일 가능성이 있지만 더 중요하게는 대상 컬럼이 될 수있을 때 동작이 변경되지 않습니다 NULL
. 자세한 내용은이 게시물을 참조하십시오 .