存在带有 HAVING 子句的子查询

Posted

技术标签:

【中文标题】存在带有 HAVING 子句的子查询【英文标题】:Exists sub-query with a HAVING clause 【发布时间】:2017-02-11 17:38:56 【问题描述】:

我正在尝试了解 EXISTS 的工作原理。

下面的查询是基于this的答案,它会查询所有SalesOrderIDs在表中有超过1条记录,其中至少一条记录有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 没有实际应用条件,只是一堆1s。为什么\那么,外部查询如何只返回Sales.SalesOrderDetail 的一部分,而不是全部?

【问题讨论】:

因为子查询中的WHERE 条件。这称为相关子查询 @GordonLinoff,需要GROUP BY 吗?没有它,它会给出相同的结果。 【参考方案1】:

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

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

希望这可以澄清。

注意:始终为列使用表别名以避免歧义。

【讨论】:

【参考方案2】:

内部SELECT 1 ... 不会总是返回1。

当内部WHERE/HAVING 条件不满足时,您将不会得到 1 返回。相反,什么都没有,我的意思是 SQL Server Management Studio(如果我没记错的话)根本不会显示任何结果,甚至内部 SELECT 1 的 NULL 都不会显示,因此该特定行的整个外部 WHERE 都会失败。

因此,如果EXISTS(...) 不存在,您的部分外部查询结果集将被截断,使用EXITS(...) 返回的总行数将更少。

【讨论】:

以上是关于存在带有 HAVING 子句的子查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL中的子查询

数据库系统原理作业七数据查询中的嵌套查询

无法在具有聚合值的 HAVING 子句中使用来自子查询表连接的单值列

mysql_数据查询_嵌套查询

sql 带有FROM子句的子查询

9)子查询