Фильтрация строк с помощью предложений 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'