使用IN子句和子查询的问题

时间:2012-10-10 11:08:36

标签: sql sql-server-2008

我有以下查询

SELECT COUNT(*) 
FROM Table1 
WHERE Column1 IN
(SELECT  Column1 FROM Table2)

实际上Table2中没有名为Column1的列。 因此,如果我们只执行子查询

 SELECT  Column1 FROM Table2

它将抛出错误 - 列名称'Column1'无效。

但是,如果我执行完整查询,我没有收到任何错误。它正在重新计算表1中的总行数。

所以我想知道为什么这个查询在这种情况下没有给出任何错误的原因以及IN子句在这种情况下的工作方式。

2 个答案:

答案 0 :(得分:2)

在子查询中,您可以从外部查询中访问列。这就是这里发生的事情:

SELECT COUNT(*) 
FROM Table1 
WHERE Column1 IN
(SELECT  Column1 FROM Table2)

也可以写成:

SELECT COUNT(*) 
FROM Table1 
WHERE Column1 IN
(SELECT Table1.Column1 FROM Table2)

如果Table2中至少有一行,则子查询将始终返回Column1的{​​{1}}值,Table1将成功。

这是我通常建议使用别名的一个原因:

IN()
如果SELECT COUNT(*) FROM Table1 t1 WHERE t1.Column1 IN (SELECT t2.Column1 FROM Table2 t2) 中没有Column1

会产生错误 - 或者,如果您在子查询中引用Table2,则更明显的是它是故意的

答案 1 :(得分:0)

返回的计数是Table1而不是Table2的结果。如果查看执行计划,您可以看到它使用LEFT SEMI JOIN进行查询,因此如果它不能连接到列,我假设将执行以下查询:

SELECT COUNT(*) 
FROM Table1 

这就是查询仍然有效并返回相同输出的原因。