使用 WHERE 和 HAVING 筛选行

SELECT 语句中的 WHERE 和 HAVING 子句可以控制用于生成结果集的源表中的行。WHERE 和 HAVING 是筛选器。这两个子句指定一系列搜索条件,只有那些满足搜索条件的行才用于生成结果集。我们称满足搜索条件的行包含在结果集中。例如,以下 SELECT 语句中的 WHERE 子句仅将行限定在特定的销售区域。

USE AdventureWorks2008R2;
GO
SELECT c.CustomerID, s.Name
FROM AdventureWorks2008R2.Sales.Customer c
JOIN AdventureWorks2008R2.Sales.Store s
ON s.BusinessEntityID = c.CustomerID
WHERE c.TerritoryID = 1;

HAVING 子句通常与 GROUP BY 子句一起使用来筛选聚合值的结果。但是,也可以不使用 GROUP BY 而单独指定 HAVING。HAVING 子句指定在 WHERE 子句筛选之后应用的其他筛选器。这些筛选器可应用于选择列表中使用的聚合函数。在下面的示例中,WHERE 子句仅限定产品销售单价超过 $100 的订单,而 HAVING 子句还将结果限制为那些仅包括 100 多个单位的订单。

USE AdventureWorks2008R2;
GO
SELECT OrdD1.SalesOrderID AS OrderID,
       SUM(OrdD1.OrderQty) AS "Units Sold",
       SUM(OrdD1.UnitPrice * OrdD1.OrderQty) AS Revenue
FROM Sales.SalesOrderDetail AS OrdD1
WHERE OrdD1.SalesOrderID in (SELECT OrdD2.SalesOrderID
    FROM Sales.SalesOrderDetail AS OrdD2
    WHERE OrdD2.UnitPrice > $100)
GROUP BY OrdD1.SalesOrderID
HAVING SUM(OrdD1.OrderQty) > 100;

WHERE 和 HAVING 子句中的搜索条件

WHERE 和 HAVING 子句中的搜索条件或限定条件可以包括:

  • 比较运算符,例如:=、< >、< 和 >

    例如,下面的查询从 H 类产品的 Product 表中检索行。

    SELECT ProductID, Name
    FROM AdventureWorks2008R2.Production.Product
    WHERE Class = 'H'
    ORDER BY ProductID;
    
  • 范围(BETWEEN 和 NOT BETWEEN)

    例如,下面的查询从其中标价为 $100 到 $500 的 Product 表中检索行。

    SELECT ProductID, Name
    FROM AdventureWorks2008R2.Production.Product
    WHERE ListPrice BETWEEN 100 and 500
    ORDER BY ListPrice;
    
  • 列表(IN 和 NOT IN)

    例如,下面的查询检索颜色列表中的产品。

    SELECT ProductID, Name
    FROM AdventureWorks2008R2.Production.Product
    WHERE Color IN ('Multi', 'Silver')
    ORDER BY ProductID;
    
  • 模式匹配(LIKE 和 NOT LIKE)

    例如,下面的查询从其中产品名称以字母 Ch 开头的 Product 表中检索行。

    SELECT ProductID, Name
    FROM AdventureWorks2008R2.Production.Product
    WHERE Name LIKE 'Ch%'
    ORDER BY ProductID;
    
    注意注意

    仅可以对 text 列使用的 WHERE 条件是返回另一个数据类型的函数(如 PATINDEX())或运算符(如 IS NULL、IS NOT NULL、LIKE 和 NOT LIKE)。

  • Null 值(IS NULL 和 IS NOT NULL)

    例如,下面的查询从其中客户的销售人员 ID 不为 NULL 的 Customer 表中检索行。

    SELECT s.Name
    FROM AdventureWorks2008R2.Sales.Customer c
    JOIN AdventureWorks2008R2.Sales.Store s
    ON c.CustomerID = S.CustomerID
    WHERE c.CustomerID IS NOT NULL
    ORDER BY s.Name;
    
    注意注意

    比较 null 值时请谨慎从事。例如,指定 = NULL 与指定 IS NULL 是不同的。有关详细信息,请参阅 空值

  • 所有记录(=ALL、>ALL、<= ALL、ANY)

    例如,下面的查询从其中已发货的产品量大于任何已发货的 H 类产品量的 SalesOrderDetail 表中检索订单和产品 ID。

    USE AdventureWorks2008R2;
    GO
    SELECT OrdD1.SalesOrderID, OrdD1.ProductID
    FROM Sales.SalesOrderDetail OrdD1
    WHERE OrdD1.OrderQty > ALL
          (SELECT OrdD2.OrderQty
           FROM Sales.SalesOrderDetail OrdD2 JOIN Production.Product Prd
                 ON OrdD2.ProductID = Prd.ProductID
           WHERE Prd.Class = 'H');
    GO
    
  • 这些条件的组合(AND、OR、NOT)

    例如,下面的查询检索标价小于 $500,产品类为 L 以及产品系列为 S 的所有产品。

    SELECT ProductID, Name
    FROM AdventureWorks2008R2.Production.Product
    WHERE ListPrice < 500
       OR (Class = 'L' AND ProductLine = 'S');
    

    请注意,当您在 WHERE 子句中搜索 Unicode 字符串时,请将 N 字符放在搜索字符串的前面:

    SELECT BusinessEntityID 
    FROM AdventureWorks2008R2.Sales.Store 
    WHERE Name = N'Riders Company';