Столбец не существует в предложении IN, но SQL запускается

У меня есть запрос, который использует предложение IN . Вот упрощенная версия:

 SELECT * FROM table A JOIN table B ON A.ID = B.ID WHERE B.AnotherColumn IN (SELECT Column FROM tableC WHERE ID = 1) 

tableC не имеет Column столбца, но запрос выполняется просто отлично, без сообщения об ошибке. Может ли кто-нибудь объяснить, почему?

Это будет работать, если таблица во внешнем запросе имеет столбец этого имени. Это связано с тем, что имена столбцов из внешнего запроса доступны для подзапроса, и вы можете иметь намеренное значение для выбора внешнего столбца запроса в вашем списке SELECT подзапроса.

Например:

 CREATE TABLE #test_main (colA integer) CREATE TABLE #test_sub (colB integer) -- Works, because colA is available to the sub-query from the outer query. However, -- it's probably not what you intended to do: SELECT * FROM #test_main WHERE colA IN (SELECT colA FROM #test_sub) -- Doesn't work, because colC is nowhere in either query SELECT * FROM #test_main WHERE colA IN (SELECT colC FROM #test_sub) 

Как замечает Дэмиен, самый безопасный способ защитить себя от этой не слишком очевидной «добычи» – это привычка квалифицировать имена столбцов в подзапросе:

 -- Doesn't work, because colA is not in table #test_sub, so at least you get -- notified that what you were trying to do doesn't make sense. SELECT * FROM #test_main WHERE colA IN (SELECT #test_sub.colA FROM #test_sub) 

Если вы хотите избежать этой ситуации в будущем (это объяснил Мэтт Гибсон), стоит привыкнуть всегда использовать псевдонимы для указания столбцов. Например:

 SELECT * FROM table A JOIN table B ON A.ID = B.ID WHERE B.AnotherColumn IN (SELECT C.Column FROM tableC C WHERE C.ID = 1) 

Это дало бы вам хорошее сообщение об ошибке (обратите внимание, что я также указал псевдоним в предложении where – если в таблице C не было столбца идентификатора, у вас также были бы дополнительные проблемы)