用作子查询时,错误查询有效 - 如何?为什么?
Erroneous query works when used as subquery - how? Why?
让我们考虑两个表:
- 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'.
但是,使用 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 标准行为,并非特定于单个数据库。
让我们考虑两个表:
- 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'.
但是,使用 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 标准行为,并非特定于单个数据库。