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

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

下面的查询是基于this的答案,它会查询所有SalesOrderIDs在表中有超过1条记录,其中至少一条记录有OrderQty > 1和ProductID = 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 吗?没有它,它会给出相同的结果。

标签: sql sql-server where exists


【解决方案1】:

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

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

希望这可以澄清。

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2011-04-15
      • 2017-12-22
      • 2017-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多