четверг, 21 марта 2013 г.

Как осуществить фильтрацию по агрегированным данным (HAVING)


-- Задача. Найти заказы с номером более 50000
-- на сумму более 5000$
-- при количестве позиций (ассортименте) не более 3

-- Попробуйте найти заказы с номером более 50000
SELECT
    SalesOrderID
    ,SUM(LineTotal) AS Total
    ,COUNT(DISTINCT ProductID) AS ProductQty
FROM AdventureWorks2012.Sales.SalesOrderDetail
WHERE SalesOrderID < 50000
GROUP BY SalesOrderID
ORDER BY Total DESC

-- Все ОК

-- Теперь на сумму более 5000$
-- при количестве позиций (ассортименте) не более 3
SET LANGUAGE 'Русский'
SELECT
    SalesOrderID
    ,SUM(LineTotal) AS Total
    ,COUNT(DISTINCT ProductID) AS ProductQty
FROM AdventureWorks2012.Sales.SalesOrderDetail
WHERE SalesOrderID < 50000
         AND SUM(LineTotal) > 5000
         AND COUNT(DISTINCT ProductID) <= 3
GROUP BY SalesOrderID
ORDER BY Total DESC

-- Выдает ошибку:

--Msg 147, Level 15, State 1, Line 7
--Статистическое выражение не может использоваться в предложении WHERE, если оно не содержится во вложенном запросе предложения HAVING или в списке выбора, и столбец, подвергаемый статистической обработке, не является внешней ссылкой.

-- Используем фильтрацию по результатам агрегирования в предложении HAVING (ИМЕЮЩИЕ)
SELECT
         SalesOrderID
         ,SUM(LineTotal) AS Total
         ,COUNT(DISTINCT ProductID) AS ProductQty
FROM AdventureWorks2012.Sales.SalesOrderDetail
WHERE SalesOrderID < 50000
GROUP BY SalesOrderID
HAVING SUM(LineTotal) > 5000
         AND COUNT(DISTINCT ProductID) <= 3
ORDER BY Total DESC

-- Вопросы?