【问题标题】:Select statement with "where in" returns more rows than subquery带有“where in”的 Select 语句返回的行数多于子查询
【发布时间】:2025-12-08 20:35:01
【问题描述】:

今天我们发现了 SQL Server 2012 SP1 的一些奇怪行为。我们知道如何重现问题,但我们不确定是什么原因造成的。这是一个非常笼统的例子:


假设您有一个数据库 test,它有一个表 table1,其中包含以下数据:

column1
-
1
2
3
4

您运行以下查询:

USE [test]

SELECT [column1]
FROM [test].[dbo].[table1]
WHERE [column1] IN
(SELECT TOP 5 [column1]
FROM [table1])

正如预期的那样,返回 5 行。现在运行以下查询:

USE [test]

SELECT [column1]
FROM [test].[dbo].[table1]
WHERE [column1] IN
(SELECT TOP 5 [test].[dbo].[table1].[column1]
FROM [table1])

这次返回 10 行,尽管 SELECT TOP 5 [test].[dbo].[table1].[column1] FROM [table1] 返回 5 行。


查看执行计划,我可以看出服务器正在做一些不同的事情,但我不知道为什么。

解决方案似乎是确保我们不会无缘无故地过于明确,但既然我们已经遇到了,我们要确保没有人再次导致这种行为。

【问题讨论】:

    标签: sql subquery sql-server-2012 where-in


    【解决方案1】:

    嗯,查询的上下文是造成差异的原因。

    在下面的查询中,第二个 select 语句实际上是从第一个表中选择一列。

    SELECT [column1]
    FROM [test].[dbo].[table1]
    WHERE [column1] IN
    (SELECT TOP 5 [test].[dbo].[table1].[column1]
    FROM [table1])
    

    如果你给表格一个别名,你会注意到不同的结果:

    SELECT [column1]
    FROM [test].[dbo].[table1] table1A
    WHERE [column1] IN
    (SELECT TOP 5 [test].[dbo].[table1].[column1]
    FROM [table1])
    

    此外,当您单独运行查询 SELECT TOP 5 [test].[dbo].[table1].[column1] FROM [table1] 时,您不会混淆您从哪个表中选择。

    您的查询相当于:

    Select column1 from table1
    where column1 in 
    (select column1)
    

    只要另一个表返回行,您选择的值在子查询中总是等于它自己。 这很像说 当添加到另一个集合时,给我列值等于自身的集合中的所有内容。只要其他集合不为空,列值将始终等于自身。

    【讨论】:

    • "在下面的查询中,第二个 select 语句实际上是从第一个表中选择一列。"我们知道它与上下文有关,但无法弄清楚它在做什么。这很有道理。
    最近更新 更多