Как работает group by в sql
Перейти к содержимому

Как работает group by в sql

  • автор:

Как работает group by в sql

Для группировки данных в 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, которая вычисляет количество строк в группе.

Группировка и GROUP BY в T-SQL

Стоит учитывать, что любой столбец, который используется в выражении SELECT (не считая столбцов, которые хранят результат агрегатных функций), должны быть указаны после оператора GROUP BY. Так, например, в случае выше столбец Manufacturer указан и в выражении SELECT, и в выражении GROUP BY.

И если в выражении SELECT производится выборка по одному или нескольким столбцам и также используются агрегатные функции, то необходимо использовать выражение GROUP BY. Так, следующий пример работать не будет, так как он не содержит выражение группировки:

SELECT Manufacturer, COUNT(*) AS ModelsCount FROM Products

Другой пример, добавим группировку по количеству товаров:

SELECT Manufacturer, ProductCount, COUNT(*) AS ModelsCount FROM 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

GROUP BY в MS SQL Server

Фильтрация групп. HAVING

Оператор HAVING определяет, какие группы будут включены в выходной результат, то есть выполняет фильтрацию групп.

Применение HAVING во многом аналогично применению WHERE. Только есть WHERE применяется к фильтрации строк, то HAVING используется для фильтрации групп.

Например, найдем все группы товаров по производителям, для которых определено более 1 модели:

SELECT Manufacturer, COUNT(*) AS ModelsCount FROM Products GROUP BY Manufacturer HAVING COUNT(*) > 1

HAVING в T-SQL

При этом в одной команде мы можем использовать выражения 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 FROM Products WHERE Price * ProductCount > 80000 GROUP BY Manufacturer HAVING SUM(ProductCount) > 2 ORDER BY Units DESC

В данном случае группировка идет по производителям, и также выбирается количество моделей для каждого производителя (Models) и общее количество всех товаров по всем этим моделям (Units). В конце группы сортируются по количеству товаров по убыванию.

Как работает GROUP BY в MySQL?

введите сюда описание изображения

То есть, в столбце DEPARTMENT_ID ищется уникальное (похоже на DISTINCT ) значение отдела, например, 30, затем ищутся все строки, где упоминается отдел 30 в данной таблице, из этих строк берутся значения из столбца SALARY и суммируются ( SUM ). Потом ищется другой покупатель и все повторяется. В итоге я получаю сколько получил вообще денег каждый отдел. Не понимаю момент: у меня есть 6 строк, в которых есть столбец DEPARTMENT_ID со значением 30. Какая из строк пойдет в таблицу- SELECT и почему? То есть, в таблице Employees было шесть строк с DEPARTMENT_ID 30, а в таблице- SELECT такая строка только одна. Как вообще эта группировка работает?

  • Рассмотрим группировку по двум столбцам. Ее я вообще не понимаю. Даже картинки нормальной не нашел, из которой было бы понятно. Просмотрел кучу статей и книг по этому вопросу, но не понял ничего.
  • Отслеживать
    13.7k 12 12 золотых знаков 43 43 серебряных знака 75 75 бронзовых знаков
    задан 5 дек 2016 в 9:35
    2,049 3 3 золотых знака 18 18 серебряных знаков 35 35 бронзовых знаков

    А что вас смущает? Да, при группировке выбирается первая прочитанная строка из группы, т. е., если в таблице Employees было ШЕСТЬ строк с DEPARTMENT_ID 30, то в таблице SELECT такая строка будет только ОДНА, и остальные поля, которые выбирались из первой таблицы SELECT ‘ом, но не вошли в GROUP BY , будут соответствовать первой прочитанной строке из группы с DEPARTMENT_ID = 30

    5 дек 2016 в 9:51
    где это написано, что выбирается именно ПЕРВАЯ строка? не встречал
    5 дек 2016 в 9:53
    webnotes.by/docs/sql/osobennosti-group-by-v-mysql например, тут
    5 дек 2016 в 9:55
    @Mike +1 про другие СУБД. Вообще странное поведение MySQL, первый раз счас про него прочитал 😀
    5 дек 2016 в 10:18

    2 ответа 2

    Сортировка: Сброс на вариант по умолчанию

    В выборку после group by не попадет ни одна из изначальных строк. На выходе агрегат — сумма данных в нужном разрезе. К колонкам, к которым вы явно не применили никаких групповых функций (таких как sum() ), будет применена функция «первое попавшееся». Причем только в MySQL и только при выключенной опции ONLY_FULL_GROUP_BY . В остальных СУБД запрос, в котором хотя бы к одной колонке, не являющейся разрезом указанным в group by, «забыли» применить групповую функцию выдаст ошибку.

    Как работает group by можно прикинуть в экселе. Запишите данные на лист, отсортируйте по тем полям, которые должны быть в group by . Читая отсортированные данные подряд в любом случае когда значение в очередной строке в колонках, указанных в group by отличается от значений в предыдущей — вставьте новую строку, скопируйте значения колонок group by , а в остальные поместите формулы вроде СУММ() ячеек группы под которой подводится итог. Результат group by — это именно эти вставленные итоговые записи. СУБД работает примерно по такому же алгоритму — сначала сортирует, потом суммирует идущие подряд одинаковые записи.

    Добавлю про MySQL — он все таки слишком вольно к этому относится. Старайтесь всегда явно применять групповые функции ко всем колонкам, что бы самому понимать что именно в них окажется, ибо ‘первое попавшееся’ ни чем не стандартизировано и может меняться от версии к версии и в зависимости от физического расположения записей на диске и плана выполнения запроса.

    Оператор SQL GROUP BY для группировки в запросах

    Оператор SQL GROUP BY служит для распределения строк — результата запроса — по группам, в которых значения некоторого столбца, по которому происходит группировка, являются одинаковыми. Группировку можно производить как по одному столбцу, так и по нескольким.

    Часто оператор SQL GROUP BY применяется вместе с агрегатными функциями (COUNT, SUM, AVG, MAX, MIN). В этих случаях агрегатные функции служат для вычисления соответствующего агрегатного значения ко всему набору строк, для которых некоторый столбец — общий.

    Оператор GROUP BY имеет следующий синтаксис:

    SELECT ИМЕНА_СТОЛБЦОВ FROM ИМЯ_ТАБЛИЦЫ [ WHERE УСЛОВИЕ] GROUP BY ИМЕНА_СТОЛБЦОВ

    Группировка по одному столбцу без агрегатных функций

    Если в результате запроса требуется вывести один столбец и по этому же столбцу производится группировка, то оператор GROUP BY просто выбирает уникальные значения и убирает дубликаты, то есть выполняет те же задачи, что и ключевое слово DISTINCT.

    Если вы хотите выполнить запросы к базе данных из этого урока на MS SQL Server, но эта СУБД не установлена на вашем компьютере, то ее можно установить, пользуясь инструкцией по этой ссылке .

    Скрипт для создания базы данных библиотеки, её таблиц и заполения таблиц данными — в файле по этой ссылке .

    В примерах работаем с базой данных библиотеки и ее таблицей «Книга в пользовании» (Bookinuse). Отметим, что оператор GROUP BY ведёт себя несколько по-разному в MySQL и в MS SQL Server. Эти различия будут показаны на примерах.

    Author Title Pubyear Inv_No Customer_ID
    Толстой Война и мир 2005 28 65
    Чехов Вишневый сад 2000 17 31
    Чехов Избранные рассказы 2011 19 120
    Чехов Вишневый сад 1991 5 65
    Ильф и Петров Двенадцать стульев 1985 3 31
    Маяковский Поэмы 1983 2 120
    Пастернак Доктор Живаго 2006 69 120
    Толстой Воскресенье 2006 77 47
    Толстой Анна Каренина 1989 7 205
    Пушкин Капитанская дочка 2004 25 47
    Гоголь Пьесы 2007 81 47
    Чехов Избранные рассказы 1987 4 205
    Пушкин Сочинения, т.1 1984 6 47
    Пастернак Избранное 2000 137 18
    Пушкин Сочинения, т.2 1984 8 205
    NULL Наука и жизнь 9 2018 2019 127 18
    Чехов Ранние рассказы 2001 171 31

    Пример 1. Вывести авторов выданных книг, сгруппировав их. Пишем следующий запрос:

    SELECT Author FROM BOOKINUSE GROUP BY Author

    Этот запрос вернёт следующий результат:

    Author
    NULL
    Гоголь
    Ильф и Петров
    Маяковский
    Пастернак
    Пушкин
    Толстой
    Чехов

    Как видим, в таблице стало меньше строк, так как фамилии авторов остались каждая по одной.

    В следующем примере увидим, что оператор GROUP BY не следует путать с оператором ORDER BY и поймём, чем эти операторы отличаются друг от друга.

    Пример 2. Вывести авторов и названия выданных книг, сгруппировав по авторам. Пишем следующий запрос, который допустим в MySQL:

    SELECT Author, Title FROM Bookinuse GROUP BY Author

    Этот запрос вернёт следующий результат:

    Author Title
    NULL Наука и жизнь 9 2018
    Гоголь Пьесы
    Ильф и Петров Двенадцать стульев
    Маяковский Поэмы
    Пастернак Доктор Живаго
    Пушкин Капитанская дочка
    Толстой Война и мир
    Чехов Вишнёвый сад

    Как видим, в таблице каждому автору соответствует лишь одна книга, причём та, которая в таблице BOOKINUSE является первой по порядку записей.

    Если бы нам требовалось вывести все книги, причём авторы должны были бы следовать не «вразброс», а по порядку: сначала Гоголь и все его книги, затем другие авторы и все их книги, то мы применили бы не оператор GROUP BY, а оператор ORDER BY.

    Группировка по нескольким столбцам без агрегатных функций

    И всё же вывести все записи, соответствующие значению столбца, по которому происходит группировка, можно. Но в этом случае в результирующей таблице должен появиться ещё один столбец. Такой случай проиллюстирован в следующем примере.

    Пример 3. Вывести авторов, названия выданных книг, ID пользователя и инвентарный номер выданной книги. Сгруппировать по авторам, ID пользователя и инвентарному номеру. На MySQL запрос будет следующим:

    SELECT Author, Title, Customer_ID, Inv_no FROM Bookinuse GROUP BY Author, Customer_ID, Inv_no

    Этот запрос вернёт следующий результат:

    Author Title Customer_ID Inv_no
    Гоголь Пьесы 47 81
    Ильф и Петров Двенадцать стульев 31 3
    Маяковский Поэмы 120 2
    Пастернак Избранное 18 137
    Пастернак Доктор Живаго 120 69
    Пушкин Капитанская дочка 47 25
    Пушкин Сочинения, т.1 47 6
    Пушкин Сочинения, т.2 205 8
    Толстой Воскресенье 47 77
    Толстой Война и мир 65 28
    Толстой Анна Каренина 205 7
    Чехов Вишневый сад 31 19
    Чехов Ранние рассказы 31 171
    Чехов Вишневый сад 65 5
    Чехов Избранные рассказы 120 19
    Чехов Избранные рассказы 205 4

    Как видим, в результирующей таблице присутствуют все книги всех авторов, причём авторы следуют по порядку, как если бы мы применили оператор ORDER BY. Кроме того, видно, что записи сгруппированы и по второму указанному столбцу — Customer_ID. Так, у автора Пушкина сначала перечисляются книги, выданные пользователю с Customer_ID 47, а затем — 205. У автора Чехова сначала перечисляются книги, выданные пользователю с Customer_ID 31, а затем — с другими номерами. Третий столбец, по которому происходит группировка — Inv_no — добавлен только для того, чтобы в результирующей таблице выводились все строки, соответствующие значениям ранее перечисленных столбцов для группировки, а не только уникальные.

    По-другому ведёт себя оператор GROUP BY в MS SQL Server и в случае этого запроса.

    • Группировка по одному столбцу без агрегатных функций
    • Группировка по нескольким столбцам без агрегатных функций
    • Группировка с агрегатными функциями
    • Особенности применения группировки в MS SQL Server

    Как работает group by в sql

    Группировка по нескольким столбцам

    Группировка по нескольким столбцам

    В предложениях GROUP BY можно указывать столько столбцов, сколько вам необходимо, разделяя имена элементы списка запятыми. Таким образом, путем группировки одновременно по нескольким элементам можно создавать группы внутри групп. Каждый элемент из списка GROUP BY должен обязательно присутствовать в списке выбора — другими словами, группировать можно только выбираемые элементы.

    SQL:
    SELECT region, sex, COUNT(*) AS num_clients
    FROM tbl_clients
    GROUP BY region, sex

    region sex num_clients
    California f 18
    California m 15
    Los Angeles f 42
    Los Angeles m 57
    New Jersey f 12
    New Jersey m 21
    New York f 15
    New York m 18
    Oregon f 15
    Oregon m 18
    Portland f 12
    Portland m 32
    Seattle f 37
    Seattle m 40
    Washington f 21
    Washington m 11

    Сначала строки таблицы разделяются по городам, а затем каждая полученная группа разделяется по полу клиента. В результате получается 16 групп, или наборов. После этого к каждому такому набору применяется агрегирующая функция, которая вычисляет для каждого города количество клиентов женского и мужского пола.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *