TSQL子查询Snafu

时间:2018-09-08 04:10:08

标签: sql-server tsql sql-server-2016

我发现我的子查询没有出现错误。 docs并不表示这是一个潜在的问题,因此我认为我必须缺少一些查询引擎如何工作的更基本的知识。复制:

-- create and populate two tables with unique column names
create table tbl1 (col1 int);
insert tbl1 values (1);
create table tbl2 (col2 int);
insert tbl2 values (2);

-- execute query and subquery 
select col1 from tbl1 
    where col1 in (select col1 from tbl2);

仅子查询会返回预期的错误:

Invalid column name 'col1'.

但是完整查询返回的是假结果,而不会引发错误。

query result

无论发生什么情况,是否已通过Microsoft或SQL-92标准正式记录?谢谢!

2 个答案:

答案 0 :(得分:2)

它与tbl1相关。 始终为表添加别名

这是按预期运行

create table tbl1 (col1 int);
insert tbl1 values (1);
create table tbl2 (col2 int);
insert tbl2 values (2);

-- execute query and subquery 
select col1 from tbl1 
    where col1 in (select Z.col1 from tbl2 Z);

我知道这很烦人且没有文档记录,似乎像个bug,但事实并非如此。如果您的列名称与范围内所有有效列中的 one 列匹配,则使用该列。这就是这里发生的事情。有一些编码实践可以阻止这些陷阱,即对所有事物都使用别名。

我不会将别名称为解决方法。这里没有解决方法-完全合乎逻辑。

您可以深入研究相关子查询如何工作的定义,您可能会找到答案,但我认为这是一个经验教训。

答案 1 :(得分:2)

对列'col1'的子查询引用实际上是在引用外部表:

select col1 from tbl1 
    where col1 in (select col1 from tbl2);
                          ^^^  this is 'col1' in table 'tbl1'

此行为符合预期:

select t1.col1 from tbl1 t1
    where t1.col1 in (select t2.col1 from tbl2 t2);

为避免意外结果,请始终对表使用别名。