让我们考虑两个表:
正如所料, 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'.
但是, query2 使用 query1 作为子查询,可以正常工作:
SELECT *
FROM MY_DB.dbo.MY_TABLE1 t1
WHERE t1.MY_PROBLEMATIC_COLUMN IN (
SELECT MY_PROBLEMATIC_COLUMN
FROM MY_DB.dbo.MY_TABLE2
)
从MY_DB.dbo.MY_TABLE返回所有行。
当用作子查询时,如何评估错误?
我不相信这是至关重要的,但事实上,MY_PROBLEMATIC_COLUMN的类型为varchar(50)。
我的第一个猜测是,由于某种原因,子查询被评估为NULL,然后 query2 将返回0行,因为NULL计算为false(我相信?)
DBMS:Sql Server 2000(很遗憾,我知道......)
答案 0 :(得分:2)
始终使用表别名,尤其是使用相关子查询。您认为您的查询是:
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
)
这将返回t1
中的所有非NULL值 - 假设t2
至少有一行。否则,将不会返回任何内容。
注意:这是ANSI标准行为,并非特定于单个数据库。