Временная таблица 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 с самим собой, поскольку он не существует во внутренней таблице, поэтому всегда верно

Другие вопросы по тегам