Оператор SQL HAVING
Оператор SQL HAVING є вказівником результат виконання агрегатних функцій. Агрегатною функцією в мові SQL називається функція, що повертає якесь одне значення набору значень стовпця. Такими функціями є: SQL COUNT(), SQL MIN(), SQL MAX(), SQL AVG(), SQL SUM().
Оператор SQL HAVING має наступний синтаксис:
HAVING aggregate_function(column_name) operator value
Оператор SQL HAVING аналогічний оператору SQL WHERE за тим винятком, що застосовується не для всього набору стовпців таблиці, а для набору створеного оператором SQL GROUP BY і застосовується завжди після нього.
Приклади оператора SQL HAVING. Є наступна таблиця Artists:
| Singer |
Album |
Year |
Sale |
| The Prodigy |
Invaders Must Die |
2008 |
1200000 |
| Drowning Pool |
Sinner |
2001 |
400000 |
| Massive Attack |
Mezzanine |
1998 |
2300000 |
| The Prodigy |
Fat of the Land |
1997 |
600000 |
| The Prodigy |
Music For The Jilted Generation |
1994 |
1500000 |
| Massive Attack |
100th Window |
2003 |
1200000 |
| Drowning Pool |
Full Circle |
2007 |
800000 |
| Massive Attack |
Danny The Dog |
2004 |
1900000 |
| Drowning Pool |
Resilience |
2013 |
500000 |
приклад 1. Використовуючи оператор SQL HAVING вивести назву виконавців (Singer) кількість продажів альбомів (Sale) якого більше 2000000:
SELECT Singer, SUM(Sale) FROM Artists GROUP BY Singer HAVING SUM(Sale) > 2000000
| Singer |
Sum(Sale) |
| Massive Attack |
54000000 |
| The Prodigy |
33000000 |
У результат не потрапила група Drowning Pool, оскільки загальна кількість проданих нею платівок дорівнює 1700000
приклад 2. Використовуючи оператор SQL HAVING, вивести назву виконавця, який виконувався ще до 1995 року:
SELECT Singer, MIN(Year) FROM Artists GROUP BY Singer HAVING MIN(Year) < 1995
Як працює having?
Для групування даних у T-SQL застосовуються оператори GROUP BY та HAVING , для використання яких застосовується наступний формальний синтаксис:
SELECT стовпці FROM таблиця [WHERE умова_фільтрації_рядків] [GROUP BY стовпці_для_групування] [HAVING умова_фільтрації_груп] [ORDER BY стовпці_для_сортування]
GROUP BY
Оператор GROUP BY визначає, як рядки групуватимуться.
Наприклад, згрупуємо товари за виробником
SELECT Manufacturer, COUNT(*) AS ModelsCount FROM Products GROUP BY Manufacturer
Перший стовпець у виразі SELECT - Manufacturer представляє назву групи, а другий стовпець - ModelsCount представляє результат функції Count, яка обчислює кількість рядків групи.
Варто враховувати, що будь-який стовпець, який використовується у виразі SELECT (не рахуючи стовпців, які зберігають результат агрегатних функцій), повинні бути вказані після оператора GROUP BY. Так, наприклад, у разі вище стовпець Manufacturer зазначений і у виразі SELECT, і у виразі GROUP BY.
І якщо у виразі SELECT проводиться вибірка по одному або декільком стовпцям і також використовуються агрегатні функції, необхідно використовувати вираз GROUP BY. Так, наступний приклад працювати не буде, оскільки він не містить виразу угруповання:
SELECT Manufacturer, COUNT(*) AS ModelsCount FROM Products
Інший приклад, додамо угруповання за кількістю товарів:
SELECT Manufacturer, ProductCount, COUNT(*) AS ModelsCount Products GROUP BY Manufacturer, ProductCount
Оператор GROUP BY може виконувати угруповання по безлічі стовпців.
Якщо стовпець, яким проводиться угруповання, містить значення NULL, то рядки зі значенням NULL складуть окрему групу.
Слід враховувати, що вираз GROUP BY має йти після виразу WHERE , але до виразу ORDER BY :
SELECT Manufacturer, COUNT(*) AS ModelsCount FROM Products WHERE Price > 30000 GROUP BY Manufacturer ORDER BY ModelsCount DESC
Фільтрування груп. HAVING
Оператор HAVING визначає, які групи будуть включені у вихідний результат, тобто виконує фільтрацію груп.
Застосування HAVING багато в чому аналогічне до застосування WHERE. Тільки WHERE застосовується до фільтрації рядків, то HAVING використовується для фільтрації груп.
Наприклад, знайдемо всі групи товарів за виробниками, для яких визначено понад 1 модель:
SELECT Manufacturer, COUNT(*) AS ModelsCount FROM Products GROUP BY Manufacturer HAVING COUNT(*) > 1
При цьому в одній команді ми можемо використовувати вирази WHERE та HAVING:
SELECT Manufacturer, COUNT(*) AS ModelsCount FROM Products WHERE Price * ProductCount > 80000 GROUP BY Manufacturer HAVING COUNT(*) > 1
Тобто в даному випадку спочатку фільтруються рядки: вибираються ті товари, загальна вартість яких більша за 80000. Потім вибрані товари групуються за виробниками. І далі фільтруються самі групи - вибираються ті групи, які містять понад 1 модель.
Якщо при цьому необхідно провести сортування, вираз ORDER BY йде після виразу HAVING:
SELECT Manufacturer, COUNT(*) AS Models, SUM(ProductCount) AS Units Products WHERE Price * ProductCount > 80000 GROUP BY Manufacturer HAVING SUM(ProductCount) > 2 ORDER BY Units DESC
В даному випадку угруповання йде по виробниках, а також вибирається кількість моделей для кожного виробника (Models) та загальна кількість усіх товарів по всіх цих моделях (Units). Наприкінці групи сортуються за кількістю товарів зі спадання.