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

时间:2015-06-08 11:50:21

标签: sql sql-server select subquery sql-server-2000

让我们考虑两个表:

  • MY_DB.dbo.MY_TABLE1, 包含列MY_PROBLEMATIC_COLUMN
  • MY_DB.dbo.MY_TABLE2 包含列MY_PROBLEMATIC_COLUMN

正如所料, 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(很遗憾,我知道......)

1 个答案:

答案 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标准行为,并非特定于单个数据库。