HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Агрегатные функции часто используются в запросах. Например, мы можем подсчитать количество курсов, на которые записался каждый пользователь.</p>
1 <p>Агрегатные функции часто используются в запросах. Например, мы можем подсчитать количество курсов, на которые записался каждый пользователь.</p>
2 <p>Сначала выберем уникальных пользователей в таблице course_members:</p>
2 <p>Сначала выберем уникальных пользователей в таблице course_members:</p>
3 <p><a>View On DB Fiddle</a></p>
3 <p><a>View On DB Fiddle</a></p>
4 <p>Затем для каждого пользователя подсчитаем количество курсов. Запросы будут выглядеть так:</p>
4 <p>Затем для каждого пользователя подсчитаем количество курсов. Запросы будут выглядеть так:</p>
5 <p><a>View On DB Fiddle</a></p>
5 <p><a>View On DB Fiddle</a></p>
6 <p>Проблема в том, что в нашей таблице слишком много пользователей. Писать отдельный запрос для каждого слишком долго, а еще есть вероятность кого-то пропустить.</p>
6 <p>Проблема в том, что в нашей таблице слишком много пользователей. Писать отдельный запрос для каждого слишком долго, а еще есть вероятность кого-то пропустить.</p>
7 <p>Справиться с этой сложностью помогает группировка данных, которую мы изучим в этом уроке.</p>
7 <p>Справиться с этой сложностью помогает группировка данных, которую мы изучим в этом уроке.</p>
8 <h2>Оператор GROUP BY</h2>
8 <h2>Оператор GROUP BY</h2>
9 <p>Группировка данных позволяет объединить одинаковые значения в заданных полях в группы, а затем выполнять подсчеты для каждой группы.</p>
9 <p>Группировка данных позволяет объединить одинаковые значения в заданных полях в группы, а затем выполнять подсчеты для каждой группы.</p>
10 <p>Для группировки данных существует специальный оператор GROUP BY. Запрос с подсчетом курсов каждого пользователя будет выглядеть так:</p>
10 <p>Для группировки данных существует специальный оператор GROUP BY. Запрос с подсчетом курсов каждого пользователя будет выглядеть так:</p>
11 <p>Мы могли бы создавать по отдельному запросу для каждого пользователя, но вместо этого использовали конструкцию GROUP BY user_id. В ней мы указали, что нам нужно объединить строки с одинаковыми идентификаторами user_id, вывести идентификатор и количество строк в каждой группе COUNT(*).</p>
11 <p>Мы могли бы создавать по отдельному запросу для каждого пользователя, но вместо этого использовали конструкцию GROUP BY user_id. В ней мы указали, что нам нужно объединить строки с одинаковыми идентификаторами user_id, вывести идентификатор и количество строк в каждой группе COUNT(*).</p>
12 <p>Для удобства мы отсортировали данные по идентификатору, но это необязательно:</p>
12 <p>Для удобства мы отсортировали данные по идентификатору, но это необязательно:</p>
13 <p><a>View On DB Fiddle</a></p>
13 <p><a>View On DB Fiddle</a></p>
14 <h2>Псевдонимы для столбцов</h2>
14 <h2>Псевдонимы для столбцов</h2>
15 <p>Система управления базами данных автоматически присвоила нашему второму столбцу имя count, совпадающее с именем функции. Но мы можем переименовать этот столбец, как и любой другой:</p>
15 <p>Система управления базами данных автоматически присвоила нашему второму столбцу имя count, совпадающее с именем функции. Но мы можем переименовать этот столбец, как и любой другой:</p>
16 <p><a>View On DB Fiddle</a></p>
16 <p><a>View On DB Fiddle</a></p>
17 <p>Чтобы присвоить столбцу псевдоним, нужно после его определения записать AS и указать желаемое имя. Оно должно начинаться с буквы и не должно содержать пробелов.</p>
17 <p>Чтобы присвоить столбцу псевдоним, нужно после его определения записать AS и указать желаемое имя. Оно должно начинаться с буквы и не должно содержать пробелов.</p>
18 <h2>Как работает GROUP BY</h2>
18 <h2>Как работает GROUP BY</h2>
19 <p>Теперь попытаемся выполнить следующий запрос:</p>
19 <p>Теперь попытаемся выполнить следующий запрос:</p>
20 <p>Запрос завершится с ошибкой:</p>
20 <p>Запрос завершится с ошибкой:</p>
21 <p>Ошибка в том, что СУБД не понимает, что делать со столбцом created_at - либо он должен быть в конструкции GROUP BY, либо к нему надо применить агрегатную функцию.</p>
21 <p>Ошибка в том, что СУБД не понимает, что делать со столбцом created_at - либо он должен быть в конструкции GROUP BY, либо к нему надо применить агрегатную функцию.</p>
22 <p>Чтобы лучше понять работу GROUP BY, разберемся, почему запрос выше не работает.</p>
22 <p>Чтобы лучше понять работу GROUP BY, разберемся, почему запрос выше не работает.</p>
23 <p>Дело в том, что группировка обращается к записям в таблице. Она создает из них независимые группы записей, по которым проводится анализ.</p>
23 <p>Дело в том, что группировка обращается к записям в таблице. Она создает из них независимые группы записей, по которым проводится анализ.</p>
24 <p>При работе с группой мы можем выбрать один из двух вариантов:</p>
24 <p>При работе с группой мы можем выбрать один из двух вариантов:</p>
25 <ul><li>Либо вывести поле, по которому проводим группировку. Его значение будет одинаковым для группы</li>
25 <ul><li>Либо вывести поле, по которому проводим группировку. Его значение будет одинаковым для группы</li>
26 <li>Либо применить к полю какую-либо агрегатную функцию - например, COUNT(), MAX(), MIN() или AVG(). В этом случае СУБД будет знать, как обработать несколько разных значений.</li>
26 <li>Либо применить к полю какую-либо агрегатную функцию - например, COUNT(), MAX(), MIN() или AVG(). В этом случае СУБД будет знать, как обработать несколько разных значений.</li>
27 </ul><p>Вернемся к примеру выше. В своем запросе мы не группируем данные по столбцу created_at - это не то, что нам нужно. Если бы мы это сделали, пришлось бы работать с группами, в которых совпадают идентификатор пользователя и дата создания.</p>
27 </ul><p>Вернемся к примеру выше. В своем запросе мы не группируем данные по столбцу created_at - это не то, что нам нужно. Если бы мы это сделали, пришлось бы работать с группами, в которых совпадают идентификатор пользователя и дата создания.</p>
28 <p>Кроме того, мы не указали никакой агрегатной функции для этого столбца. СУБД не понимает, что именно нужно сделать с группой разных дат создания. Нужно посчитать среднее? Или взять максимальную дату?</p>
28 <p>Кроме того, мы не указали никакой агрегатной функции для этого столбца. СУБД не понимает, что именно нужно сделать с группой разных дат создания. Нужно посчитать среднее? Или взять максимальную дату?</p>
29 <p>Давайте исправим запрос. Выведем максимальное значение поля created_at для группы. Это будет дата последней регистрации пользователя на курс:</p>
29 <p>Давайте исправим запрос. Выведем максимальное значение поля created_at для группы. Это будет дата последней регистрации пользователя на курс:</p>
30 <p><a>View on DB Fiddle</a></p>
30 <p><a>View on DB Fiddle</a></p>
31 <h2>Выводы</h2>
31 <h2>Выводы</h2>
32 <p>В этом уроке мы изучили оператор GROUP BY. Теперь вы можете объединять одинаковые записи в группы и считать для этих групп агрегатные функции.</p>
32 <p>В этом уроке мы изучили оператор GROUP BY. Теперь вы можете объединять одинаковые записи в группы и считать для этих групп агрегатные функции.</p>
33 <p>Важно помнить, что поля, которые вы будете выводить в запросе, нужно указывать в операторе GROUP BY или применять к ним агрегатную функцию.</p>
33 <p>Важно помнить, что поля, которые вы будете выводить в запросе, нужно указывать в операторе GROUP BY или применять к ним агрегатную функцию.</p>