用作子查询时,错误查询有效 - 如何?为什么?

Erroneous query works when used as subquery - how? Why?

让我们考虑两个表:

正如预期的那样,query1:

SELECT MY_PROBLEMATIC_COLUMN 
FROM MY_DB.dbo.MY_TABLE2

结果:

Server: Msg 207, Level 16, State 3, Line 1
Invalid column name 'MY_PROBLEMATIC_COLUMN'.

但是,使用 query1 作为子查询的 query2 有效:

SELECT *
FROM MY_DB.dbo.MY_TABLE1 t1
WHERE t1.MY_PROBLEMATIC_COLUMN IN (
            SELECT MY_PROBLEMATIC_COLUMN 
            FROM MY_DB.dbo.MY_TABLE2
            ) 

和 returns all 行来自 MY_DB.dbo.MY_TABLE.

erroneous作为子查询是怎么求值的?

我不认为它很重要,但事实上,MY_PROBLEMATIC_COLUMN 是 varchar(50) 类型。

我的第一个猜测是由于某种原因子查询被评估为 NULL,但是 query2 将 return 0 行,因为 NULL 评估为 false(我相信?)

DBMS:Sql Server 2000(悲伤,我知道...)

总是使用table别名,尤其是相关子查询。您认为您的查询是:

SELECT t1.*
FROM MY_DB.dbo.MY_TABLE1 t1
WHERE t1.MY_PROBLEMATIC_COLUMN IN (
            SELECT t2.MY_PROBLEMATIC_COLUMN 
            FROM MY_DB.dbo.MY_TABLE2 t2
            ) 

但是,由于 t2.MY_PROBLEMATIC_COLUMN 不存在,SQL 避免了错误并在外部范围中查找列。查询解释为:

SELECT t1.*
FROM MY_DB.dbo.MY_TABLE1 t1
WHERE t1.MY_PROBLEMATIC_COLUMN IN (
            SELECT t1.MY_PROBLEMATIC_COLUMN 
            FROM MY_DB.dbo.MY_TABLE2 t2
            ) 

这将 return t1 中的所有非 NULL 值——假设 t2 至少有一行。否则,不会 returned.

注意:这是 ANSI 标准行为,并非特定于单个数据库。