3

为什么 SQL Server 会这样。我在 SQL 2005 上运行它。

IN 子句不验证子查询中的列名,而是根据外部查询中的表名对其进行验证。这是获取的示例

Create table #table1(col1 int, col2 char(10), col3 char(15));

Create table #table2(col10 int, col11 char(10), col2 char(15));


insert into #table1(col1, col2, col3)
select 1, 'one', 'three'

insert into #table1(col1, col2, col3)
select 2, 'two', 'three'

insert into #table1(col1, col2, col3)
select 3, 'three', 'four'


insert into #table2(col10, col11, col2)
select 1, 'one', 'three'

insert into #table2(col10, col11, col2)
select 2, 'two', 'three'

insert into #table2(col10, col11, col2)
select 3, 'three', 'four'


select * from #table1
where col1 IN
(select col1 from #table2)

好像我只是选择“从#table2中选择col1”并运行它会吐一个错误

Msg 207, Level 16, State 1, Line 1
Invalid column name 'col1'.
4

2 回答 2

13

为什么?因为能够在子查询中引用来自外部查询的列通常很有用。没有可以用来关闭此行为的设置,但是如果您养成使用别名的习惯,您应该避免使用它的大多数问题:

select * from #table1 t1
where t1.col1 IN
(select t2.col1 from #table2 t2)

会产生错误。

于 2012-09-07T13:39:13.343 回答
6

问题不在于 IN 子句。

这个:

SELECT * 
  FROM #table1
 WHERE col1 IN (SELECT col1 
                  FROM #table2)

...有效,因为假设优化器col1来自#table1。如果您使用表别名,那么就没有歧义:

SELECT t1.* 
  FROM #table1 t1
 WHERE t1.col1 IN (SELECT t2.col1 
                     FROM #table2 t2)

...你会得到Msg 207: Invalid column error.

这与使用 DELETE 和 UPDATE 语句时的原则相同,因为典型语法不允许您为要删除或更新的表设置别名。

于 2012-09-07T13:39:33.123 回答