Временная таблица MSSQL возвращает все строки при использовании подзапроса IN
Я недавно наткнулся на этот пример. Почему запрос возвращает все строки при использовании неопределенного столбца во временной таблице "id". Это работает только для идентификатора, и это работает только при использовании подзапроса IN.
DECLARE @test TABLE
( Id INT)
INSERT INTO @test
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3
SELECT * FROM @test
SELECT 1 AS 'myid'
INTO #tmpId
--Returns one rows - OK
SELECT * FROM @test WHERE id in (SELECT myId FROM #tmpId)
--Returns all rowns - WHY
SELECT * FROM @test WHERE id in (SELECT id FROM #tmpId)
--ERROR - no column - OK
SELECT * FROM @test WHERE id in (SELECT asdf FROM #tmpId)
--ERROR - no column - OK
SELECT id FROM #tmpId
DROP TABLE #tmpId
2 ответа
Решение
Всегда используйте псевдонимы таблиц, когда у вас есть несколько таблиц. Первый запрос должен быть записан как:
SELECT t.* FROM @test t WHERE t.id in (SELECT tt.myid FROM #tmpId tt)
Это делает то, что вы хотите.
Если вы напишите второй запрос как:
SELECT t.* FROM @test t WHERE t.id in (SELECT tt.id FROM #tmpId tt)
Вы получите ошибку. Ваша версия интерпретируется как коррелированный подзапрос:
SELECT t.* FROM @test t WHERE t.id in (SELECT t.id FROM #tmpId tt)
Это не то, что вы хотите. Это эквивалентно:
SELECT t.* FROM @test t WHERE t.id IS NOT NULL;
Во втором запросе вы сравниваете столбец Id с самим собой, поскольку он не существует во внутренней таблице, поэтому всегда верно