Поделиться через


Фильтрация строк с помощью предложений WHERE и HAVING

Предложения WHERE и HAVING в инструкции SELECT управляют строками исходной таблицы, используемыми для формирования результирующего набора. Предложения WHERE и HAVING являются фильтрами. Они определяют серию условий поиска, а в формировании результирующего набора участвуют лишь те строки, которые удовлетворяют этим условиям поиска. Строки, удовлетворяющие этим условиям поиска, называются подходящими для участия в формировании результирующего набора. Например, предложение WHERE в следующей инструкции SELECT фильтрует строки, подходящие только для конкретного региона продаж.

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

Предложение HAVING обычно используется вместе с предложением GROUP BY для фильтрации результатов статистических значений. Однако предложение HAVING можно использовать отдельно от GROUP BY. Предложение HAVING определяет дополнительные фильтры, используемые после фильтров предложения WHERE. Эти фильтры можно применять в статистической функции, используемой в списке выбора. В следующем примере предложение WHERE отбирает лишь те заказы, где цена за единицу превышает $100 долларов, а предложение HAVING выделяет из отобранных результатов только те, что предусматривают поставку свыше 100 единиц.

USE AdventureWorks;
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, могут включать в себя следующее.

  • Операторы сравнения, например: =, < >, < и >

    Так, следующий запрос получает те строки таблицы Product, где речь идет о продуктах, относящихся к классу H.

    SELECT ProductID, Name
    FROM AdventureWorks.Production.Product
    WHERE Class = 'H'
    ORDER BY ProductID
    
  • Диапазоны (BETWEEN и NOT BETWEEN).

    К примеру, следующий запрос получает строки таблицы Product со справочными ценами в диапазоне от 100 долларов до 500 долларов.

    SELECT ProductID, Name
    FROM AdventureWorks.Production.Product
    WHERE ListPrice BETWEEN 100 and 500
    ORDER BY ListPrice
    
  • Списки (IN, NOT IN).

    К примеру, следующий запрос получает данные о продуктах, цвета которых указаны в списке.

    SELECT ProductID, Name
    FROM AdventureWorks.Production.Product
    WHERE Color IN ('Multi', 'Silver')
    ORDER BY ProductID
    
  • Сопоставление с шаблоном (LIKE и NOT LIKE).

    Например, следующий запрос получает строки таблицы Product, в которых название продукта начинается с букв Ch.

    SELECT ProductID, Name
    FROM AdventureWorks.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).

    Так, следующий запрос получает строки таблицы Customer, в которых идентификатор менеджера по продажам заказчика не имеет значения NULL.

    SELECT s.Name
    FROM AdventureWorks.Sales.Customer c
    JOIN AdventureWorks.Sales.Store s
    ON c.CustomerID = S.CustomerID
    WHERE c.SalesPersonID IS NOT NULL
    ORDER BY s.Name
    
    ПримечаниеПримечание

    При сравнении значений NULL следует проявлять осторожность. К примеру, выражение = NULL не эквивалентно выражению IS NULL. Дополнительные сведения см. в разделе Значения NULL.

  • Все записи (=ALL, >ALL, <= ALL, ANY).

    Так, следующий запрос получает из таблицы SalesOrderDetail коды заказов и продуктов, объемы поставок по которым превышают объемы любой поставки продуктов класса H.

    USE AdventureWorks;
    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 AdventureWorks.Production.Product
    WHERE ListPrice < 500
       OR (Class = 'L' AND ProductLine = 'S')
    

    Обратите внимание, что при поиске строки в Юникоде в предложении WHERE перед строкой поиска должен быть указан символ N.

    SELECT CustomerID 
    FROM AdventureWorks.Sales.Store 
    WHERE Name = N'Berglunds snabbkp'