use*_*441 3 sql sql-server sql-server-2005
为什么SQL服务器会以这种方式运行.我在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)
Run Code Online (Sandbox Code Playgroud)
就好像我只选择"从#table2中选择col1"并运行它吐出一个错误
Msg 207, Level 16, State 1, Line 1
Invalid column name 'col1'.
Run Code Online (Sandbox Code Playgroud)
Dam*_*ver 13
为什么?因为能够在子查询中引用外部查询中的列通常很有用.没有可用于关闭此行为的设置,但如果您养成使用别名的习惯,则应避免使用别名的大多数问题:
select * from #table1 t1
where t1.col1 IN
(select t2.col1 from #table2 t2)
Run Code Online (Sandbox Code Playgroud)
会产生错误.
这不是IN条款的问题.
这个:
SELECT *
FROM #table1
WHERE col1 IN (SELECT col1
FROM #table2)
Run Code Online (Sandbox Code Playgroud)
...有效,因为假设优化器col1来自#table1.如果您使用表别名,那么没有歧义:
SELECT t1.*
FROM #table1 t1
WHERE t1.col1 IN (SELECT t2.col1
FROM #table2 t2)
Run Code Online (Sandbox Code Playgroud)
......你会得到的Msg 207: Invalid column error.
这与使用DELETE和UPDATE语句时的原理相同,因为典型语法不允许您对要删除或更新的表进行别名.
| 归档时间: |
|
| 查看次数: |
233 次 |
| 最近记录: |