在同一查询中使用 HAVING 和 WHERE 子句 (Visual Database Tools)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsAnalytics 平台系统(PDW)

在某些情况下,你可能希望在将条件应用于整个组(使用 HAVING 子句)之前,从组(使用 WHERE 子句)中排除单个行。

HAVING 子句类似于 WHERE 子句,但仅适用于整个组(即表示组的结果集中的行),而 WHERE 子句适用于各个行。 查询可以同时包含 WHERE 子句和 HAVING 子句。 在这种情况下:

  • 首先将 WHERE 子句应用于 关系图 窗格中的表或表值对象的每一行。 仅对满足 WHERE 子句中条件的行进行分组。

  • 然后将 HAVING 子句应用于结果集中的行。 只有满足 HAVING 条件的组才会显示在查询输出中。 只能将 HAVING 子句应用于既在 GROUP BY 子句中出现又在聚合函数中的列。

在两个联接表上指定 WHERE 和 HAVING 子句

注意

本文中使用的数据库是 pubs 数据库,可从 Northwind 获取,并在 GitHub 上发布用于 Microsoft SQL Server 的示例数据库。

例如,假设你正在联接 titlespublishers 表,以创建一个查询,其中显示了一组出版商的平均图书价格。 你只想看到一组特定出版商的平均价格 - 也许只有加州的出版商。 即便如此,你也只有在平均价格超过10.00美元时才想查看。

可以通过包括一个 WHERE 条款来建立第一个条件,该条款在计算平均价格之前放弃任何不在加州的出版商。 第二个条件需要 HAVING 子句,因为条件基于分组和汇总数据的结果。 生成的 SQL 语句可能如下所示:

SELECT titles.pub_id, AVG(titles.price)
FROM titles INNER JOIN publishers
   ON titles.pub_id = publishers.pub_id
WHERE publishers.state = 'CA'
GROUP BY titles.pub_id
HAVING AVG(price) > 10;

在 SQL Server Management Studio 的 Visual Database Tools 中,可以在 条件 窗格中创建 HAVING 子句和 WHERE 子句。 默认情况下,如果为列指定搜索条件,则条件将成为 HAVING 子句的一部分。 但是,可以将条件更改为 WHERE 子句。

可以创建涉及同一列的 WHERE 子句和 HAVING 子句。 为此,必须将列两次添加到 Criteria 窗格中,然后将一个实例指定为 HAVING 子句的一部分,另一个实例作为 WHERE 子句的一部分。

在聚合查询中指定 WHERE 条件

  1. 指定查询的组。 有关详细信息,请参阅 查询结果(Visual Database Tools)中的组行。

  2. 如果该列尚未存在于“标准” 窗格中,请添加您希望用于 WHERE 条件的列。

  3. 清除 输出 列,除非数据列是 GROUP BY 子句的一部分或包含在聚合函数中。

  4. 筛选器 列中,指定 WHERE 条件。 查询和视图设计器将条件添加到 SQL 语句的 HAVING 子句。

    注意

    此过程示例中所示的查询联接两个表,titlespublishers

    此时,SQL 语句包含 HAVING 子句。

    SELECT titles.pub_id, AVG(titles.price)
    FROM titles INNER JOIN publishers
        ON titles.pub_id = publishers.pub_id
    GROUP BY titles.pub_id
    HAVING publishers.state = 'CA'
    
  5. 分组依据 列中,从组和摘要选项列表中选择 位置。 查询和视图设计器从 SQL 语句中的 HAVING 子句中删除条件,并将其添加到 WHERE 子句。

    SQL 语句更改为包含 WHERE 子句:

    SELECT titles.pub_id, AVG(titles.price)
    FROM titles INNER JOIN publishers
        ON titles.pub_id = publishers.pub_id
    WHERE publishers.state = 'CA'
    GROUP BY titles.pub_id;