MySQL Речення GROUP BY та HAVING з прикладами
⚡ Розумний підсумок
Речення SQL GROUP BY та HAVING перетворюють детальні рядки на зведені звіти. GROUP BY згортає рядки з однаковими значеннями в один рядок на групу, тоді як HAVING фільтрує ці групи після застосування агрегатних функцій, таких як COUNT.

Що таке речення SQL GROUP BY?
Речення GROUP BY — це команда SQL, яка використовується для групувати рядки, які мають однакові значенняВін записується всередині оператора SELECT і зазвичай використовується разом з агрегатними функціями для створення зведених звітів з бази даних.
Ось що воно робить: воно підсумовує дані зберігаються в базі даних. Запити, що містять речення GROUP BY, називаються згрупованими запитами, і вони повертають один рядок для кожного згрупованого елемента.
Синтаксис SQL GROUP BY
Тепер, коли призначення речення зрозуміле, розглянемо синтаксис простого згрупованого запиту.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
ТУТ
- "Оператори SELECT…«це стандарт» SQL SELECT командний запит.
- "GROUP BY ім'я_стовпця1«це речення, яке виконує групуping на основі column_name1.
- "[, назва_стовпця2, …]«необов’язковий» і представляє інші назви стовпців, коли групаping виконується на кількох стовпцях.
- "[НАЯВНІСТЬ стану]” є необов’язковим і використовується для обмеження рядків, на які впливає речення GROUP BY. Він подібний до ДЕ ЗАКЛАД, за винятком того, що його застосовують після групиping.
Гроуping Використання одного стовпця
Найшвидший спосіб побачити ефект від використання речення SQL GROUP BY – це порівняти незгрупований запит із згрупованим. Почніть із простого запиту, який повертає кожен запис статі в таблиці members.
SELECT `gender` FROM `members`;
| пол |
|---|
| жінка |
| жінка |
| чоловік |
| жінка |
| чоловік |
| чоловік |
| чоловік |
| чоловік |
| чоловік |
Повертається дев'ять рядків, і кожне значення повторюється. Припустимо, що нам потрібні унікальні значення для статі. У наведеному нижче запиті додано речення GROUP BY.
SELECT `gender` FROM `members` GROUP BY `gender`;
Виконання наведеного вище сценарію в MySQL Верстак проти myflixdb дає нам такі результати.
| пол |
|---|
| жінка |
| чоловік |
Зверніть увагу, що повернуто лише два рядки, оскільки таблиця містить лише два типи статі. Речення GROUP BY згрупувало всіх членів «Male» разом і повернуло для них один рядок, і те саме було зроблено з членами «Female».
Гроуping Використання кількох стовпців
Гроуping Значення в одному стовпці часто занадто грубе для справжнього звіту. GROUP BY приймає список стовпців, розділених комами, а комбінація їхніх значень визначає кожну групу.
Припустимо, що нам потрібен список значень category_id фільму та відповідні роки випуску цих фільмів. Спочатку розгляньте результат цього простого запиту.
SELECT `category_id`, `year_released` FROM `movies`;
| category_id | year_released |
|---|---|
| 1 | 2011 |
| 2 | 2008 |
| NULL | 2008 |
| NULL | 2010 |
| 8 | 2007 |
| 6 | 2007 |
| 6 | 2007 |
| 8 | 2005 |
| NULL | 2012 |
| 7 | 1920 |
| 8 | NULL |
| 8 | 1920 |
Виділені рядки показують, що результат містить дублікати. Виконання того ж запиту з GROUP BY видаляє їх.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Виконання наведеного вище сценарію в MySQL Аналіз Workbench на myflixdb дає нам наступні результати, показані нижче.
| category_id | year_released |
|---|---|
| NULL | 2008 |
| NULL | 2010 |
| NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
Речення GROUP BY працює як з category_id, так і з year_released для ідентифікації створеного рядки. Два дублікати рядків для категорії 6 у 2007 році об’єдналися в один.
Практичне правило: Якщо ідентифікатор категорії однаковий, але рік випуску відрізняється, рядок вважається унікальним. Якщо ідентифікатор категорії та рік випуску однакові для кількох рядків, рядки є дублікатами, і відображається лише один з них.
Гроуping та агрегатні функції
Видалення дублікатів корисне, але справжня сила групи...ping з’являється, коли його сполучено з сукупність функційАгрегатна функція обчислює одне значення для кожної групи: COUNT підраховує рядки, SUM додає значення, а AVG, MIN та MAX описують розкид.
Припустимо, нам потрібна загальна кількість учасників чоловічої та жіночої статі в базі даних. Скрипт нижче робить це.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Виконання наведеного вище сценарію в MySQL Аналіз Workbench для myflixdb дає нам такі результати.
| пол | COUNT(`номер_членства`) |
|---|---|
| жінка | 3 |
| чоловік | 6 |
Рядки групуються за кожним унікальним значенням статі, а кількість рядків у кожній групі підраховується агрегатною функцією COUNT. Дев'ять записів-членів об'єднуються у два підсумкові рядки.
Обмеження результатів запиту за допомогою речення HAVING
ГроуpingНе завжди потрібні для кожного рядка таблиці. Іноді звіт має бути обмежений заданим критерієм, і саме це і є завданням речення HAVING.
Припустимо, нам потрібно знати всі роки випуску для категорії фільмів з ідентифікатором 8. Наведений нижче скрипт досягає цього результату.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Виконання наведеного вище сценарію в MySQL Аналіз Workbench на myflixdb дає нам наступні результати, показані нижче.
| movie_id | назву | директор | year_released | category_id |
|---|---|---|---|---|
| 9 | Honey moonERS | Джон Шульц | 2005 | 8 |
| 5 | Татові маленькі дівчатка | NULL | 2007 | 8 |
Тільки фільми з ідентифікатором категорії 8 були збережені за умовою HAVING.
Увага! MySQL У версіях 5.7 та пізніших режим ONLY_FULL_GROUP_BY увімкнено за замовчуванням, і в цьому режимі SELECT * з реченням GROUP BY відхиляється, оскільки movie_id, title та director не є ні згрупованими, ні агрегованими. У робочому середовищі чітко назвіть згруповані стовпці, наприклад ВИБЕРІТЬ category_id, year_released FROM movies GROUP BY category_id, year_released HAVING category_id = 8;
ДЕ проти HAVING проти GROUP BY проти ORDER BY
Початківці часто змішують ці чотири речення, оскільки всі вони формують результуючий набір. Різниця полягає в коли MySQL застосовує їх: WHERE виконується перед групуванням рядків, HAVING виконується після, а ORDER BY виконується останнім.
| Стаття | Що вона робить | Коли воно працює | Приймає агрегатні функції |
|---|---|---|---|
| ДЕ | Фільтрує окремі рядки перед будь-якою групоюping. | Перед GROUP BY | Немає |
| GROUP BY | Згортає рядки з однаковими значеннями в один рядок на групу. | Після ДЕ | Не підтримується |
| ВІД | Фільтрує групи, створені за допомогою GROUP BY. | Після GROUP BY | Так, наприклад, HAVING COUNT(*) > 2 |
| СОРТУВАТИ ЗА | Сортує рядки, що переживають попередні речення. | Прізвище | Так, агрегатний псевдонім можна відсортувати |
Практичний наслідок — це вплив на продуктивність. Фільтрація за допомогою WHERE видаляє рядки перед групою.ping робота починається, тому умова, яка не залежить від агрегованого результату, належить до WHERE, а не до HAVING.
