SQL Server (截至当前最新补丁版本2005 SP4, 2008 SP2), 存在一个非常隐蔽的语法问题:当子查询中不存在一个列名A, 但在外层查询中存在列名A,则语法不报错,返回不合理的结果。示例如下:
create table t_test1(col1 int);
insert into t_test1 values(1);
create table t_test2 (col1 int, col2 int);
insert into t_test2 values(1, 10);
insert into t_test2 values(2, 20);
insert into t_test2 values(3, 30);
select * from t_test2 where col2 in (select col2 from t_test1);
-- 最后这个语句,不但未报错"找不到列col2", 而且返回来以下结果集
col1 col2
----------- -----------
1 10
2 20
3 30
(3 行受影响)
原因为: 命令解释进程先解释内层子查询"select col2 from t_test1",这时发现t_test1中没有col2这一列; 它然后再向外层查询寻求解释,恰好发现 外层的t_test2中,含有col2,结果导致它解释后的实际执行的命令,类似于这个语句执行的命令:select * from t_test2 as o where col2 in (select o.col2 from t_test1 as i);
解决方法: 在子查询的列名前,指定表名(或伪名)。
正确写法:select * from t_test2 where col2 in (select i.col2 from t_test1 as i);
