SQL 服务器在子查询中使用 IN 运算符似乎是一个 BUG?

SQL Server using IN operator with subquery seems to be a BUG?

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.

以上 3 SQL 语句在 SQL Server 2008 - 2017 中都是 运行 OK。

由于 f1 没有 tablex 前缀并且不在 tablex 中,因此它从 table1 绑定到 f1。当然 table1.f1(table1.f1).

这不是错误,这就是绑定在 SQL 中的工作方式。见 "Subqueries (SQL Server)" - "Qualifying column names in subqueries":

(...) If a column does not exist in the table referenced in the FROM clause of a subquery, it is implicitly qualified by the table referenced in the FROM clause of the outer query. (...)

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

... in (select tablex.f1 from tablex)

你会得到你期望的错误。

您还可以使用 table 别名来缩短限定列,如:

... in (select x.f1 from tablex x)