SQL Server 使用带有子查询的 IN 运算符似乎是一个 BUG?

Gin*_*ger 1 sql sql-server sql-server-2017

select f1 
from table1 
where f1 in (select f1) 
--running OK.

select f1 
from table1 
where f1 in (select f1 from tablex) 
-- even the column f1 does not exist in tablex, running OK.

delete from table1 
where f1 in (select f1 from tablex)
--If you do this, you may have an accident (delete all records from table1) 
--even the column f1 does not exist in tablex.
Run Code Online (Sandbox Code Playgroud)

以上 3 条 SQL 语句在 SQL Server 2008 - 2017 中都运行正常。

sti*_*bit 7

由于f1没有前缀tablex并且不在tablex它绑定到f1from table1。当然table1.f1是在(table1.f1).

这不是错误,这就是 SQL 中绑定的工作方式。请参阅“子查询 (SQL Server)”-“子查询中的限定列名”

(...) 如果子查询的 FROM 子句中引用的表中不存在列,则它由外部查询的 FROM 子句中引用的表隐式限定。(……)

这是一个很好的例子,为什么养成总是限定列的习惯会很有用——至少当涉及多个表时(通过子查询、连接等)。尝试

... in (select tablex.f1 from tablex)
Run Code Online (Sandbox Code Playgroud)

你会得到你期望的错误。

您还可以使用表别名来缩短限定列,如下所示:

... in (select x.f1 from tablex x)
Run Code Online (Sandbox Code Playgroud)