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中都可以正常运行。
谁能告诉我,为什么?
由于f1
没有以tablex
开头并且不在tablex
中,因此它从f1
绑定到table1
。当然table1.f1
在(table1.f1)
中。
这不是错误,这是绑定在SQL中的工作方式。参见"Subqueries (SQL Server)" - "Qualifying column names in subqueries":
(...)如果子查询的FROM子句中引用的表中不存在某列,则该列将由外部查询的FROM子句中所引用的表隐式限定。 (...)
这是一个很好的例子,为什么养成始终限定列的习惯很有用-至少在涉及多个表(通过子查询,联接等)时如此。尝试
... in (select tablex.f1 from tablex)
您将得到您期望的错误。
您还可以使用表别名来缩短限定的列,如:
... in (select x.f1 from tablex x)