存在带有HAVING子句的子查询

时间:2017-02-11 17:38:57

标签: sql sql-server where exists

我试图了解EXISTS的工作方式。

以下查询基于this答案,并查询表中包含多条记录的所有SalesOrderID,其中至少有一条记录为OrderQty > 1ProductID = 777

USE AdventureWorks2012;
GO
SELECT  SalesOrderID, OrderQty, ProductID
FROM    Sales.SalesOrderDetail s
WHERE   EXISTS
        (   SELECT  1
            FROM    Sales.SalesOrderDetail s2
            WHERE   s.SalesOrderID = s2.SalesOrderID
            GROUP BY SalesOrderID
            HAVING COUNT(*) > 1
            AND COUNT(CASE WHEN OrderQty > 1 AND ProductID = 777 THEN 1 END) >= 1
        );

我不明白的是:子查询返回一个在每一行上填充值1的单一列表。所以我理解它的方式,外部查询中的WHERE没有实际应用的条件,只有一堆1。为什么\如何,外部查询只返回Sales.SalesOrderDetail的一部分,而不是整个?

2 个答案:

答案 0 :(得分:0)

内部SELECT 1 ...并不总是返回1.

如果未满足内部WHERE/HAVING条件,则不会返回1。相反,什么都没有,我的意思是SQL Server Management Studio(如果我没记错的话)将显示NO结果,内部SELECT 1甚至不会为NULL,从而导致整个外部WHERE失败行。

因此,如果EXITS(...)不存在,则外部查询结果集的一部分将被截断,并且EXISTS(...)返回的总行数将会减少。

答案 1 :(得分:0)

EXISTS中发生的情况是,它只检查外部表中的记录是否满足内部查询中给出的条件。这就是为什么我们指定“1”而不是IN,我们需要指定各列(并检查每条记录的数据)。

因此,它不会返回任何一堆1并验证它。顾名思义,它只根据给定的条件检查记录是否存在。

希望这澄清。

注意:始终对列使用表别名以防止歧义。