JavaRush/Курсы/Модуль 4. Работа с БД/Группировка по нескольким колонкам

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

Открыта

4.1 Колонки при группировке

Что еще очень важно, так это то, что если ты группируешь записи, то в разделе SELECT можно указывать только колонки, по которым группируются данные.

Ты не можешь написать запрос типа и указать в разделе SELECT колонку name:

SELECT brand, name
FROM product
GROUP BY brand

У тебя в таблице product есть куча строк с полем name, и не ясно значение какой строки нужно сюда подставить. Подумай еще раз: ты хочешь узнать количество продуктов каждого бренда и как в результирующую таблицу может попасть имя продукта?

Если ты используешь оператор GROUP BY, то в твой результат не могут попасть обычные строки, а только колонки по которым группируются данные и “вычисляемые колонки”, такие как COUNT(*)

4.2 Группировка по вычисляемым колонкам

Зато ты можешь выполнять группировку по нескольким колонкам и даже по вычисляемым колонкам. Пример:

SELECT
YEAR(join_date) AS hire_year,
COUNT(*) AS total
FROM employee
GROUP BY hire_year

И результат такого запроса:

hire_year total
2012 1
2013 1
2014 1
2015 2
2018 1

Давай разберем наш запрос.

В таблице employee у каждого сотрудника уникальная дата найма, поэтому сгруппировать данные по ней не получится – для каждой даты будет одна запись и группировка не будет иметь особого смысла. Но вот если мы перейдем от даты найма к году найма, то вполне может быть ситуация, когда в один и тот же год компания наняла нескольких сотрудников.

Давай еще раз посмотрим, как будет выглядеть эта таблица до группировки:

SELECT
 	id,
 	name,
 	YEAR(join_date) AS hire_year,
 	join_date
FROM employee

И результат такого запроса:

id name hire_year join_date
1 Иванов Иван 2012 2012-06-30
2 Петров Петр 2013 2013-08-12
3 Иванов Сергей 2014 2014-01-01
4 Рабинович Мойша 2015 2015-05-12
5 Кириенко Анастасия 2015 2015-10-10
6 Васька 2018 2018-11-11

А вот уже эту результирующую таблицу вполне можно сгруппировать по hire_year и узнать сколько людей было нанято в конкретный год.

4.3 Группировка по нескольким колонкам

Теперь давай попробуем узнать сколько сотрудников мы наняли в каждый месяц каждого года. Для этого нам нужно добавить в запрос не одно, а сразу два вычисляемых поля – год найма (hire_year) и месяц найма (hire_month).

Давай напишем такой запрос:

SELECT
 	id,
 	name,
 	YEAR(join_date) AS hire_year,
 	MONTH(join_date) AS hire_month,
 	join_date
FROM employee

И результат такого запроса:

id name hire_year hire_month join_date
1 Иванов Иван 2012 6 2012-06-30
2 Петров Петр 2013 8 2013-08-12
3 Иванов Сергей 2014 1 2014-01-01
4 Рабинович Мойша 2015 5 2015-05-12
5 Кириенко Анастасия 2015 10 2015-10-10
6 Васька 2018 11 2018-11-11

Если мы сгруппируем данные этой результирующей таблицы по месяцам, то просто объединим людей в группы, не обращая внимания на год их найма. А нам нужно чтобы в результирующей таблице было три колонки: год, месяц и количество нанятых сотрудников.

Для этого после оператора GROUP BY нужно использовать название не одной колонки, а двух. Пример:

SELECT
 	YEAR(join_date) AS hire_year,
 	MONTH(join_date) AS hire_month,
 	COUNT(*) AS total
FROM employee
GROUP BY hire_year, hire_month

И результат такого запроса:

hire_year hire_month total
2012 6 1
2013 8 1
2014 1 1
2015 5 1
2015 10 1
2018 11 1

Записей в таблице у нас мало, так что в колонке total везде стоят единицы. И кстати, обратите внимание, что чем по большему количеству колонок мы группируем, тем больше у нас строк в результате.

1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
task0232
Напиши запрос, который покажет количество студентов (таблица students) заочников (is_full_time = 'no') и стационара (is_full_time = 'yes').
1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
task0233
Напиши запрос, который из таблицы employee выберет информацию о том, сколько сотрудников родилось (date_of_birth) в определенном году.
1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
task0234
Напиши запрос, который из таблицы employee выберет информацию о том, сколько сотрудников родилось (date_of_birth) в определенном году. Колонка с годом в результате должна иметь название year_of_birth.
1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
task0235
Напиши запрос, который из таблицы employee выберет информацию о том, сколько сотрудников, в должности (position) которых присутствует слово 'developer', родилось (date_of_birth) в определенном году. Колонка с годом в результате должна иметь название year_of_birth.
1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
task0236
Напиши запрос, который из таблицы employee выберет информацию о том, сколько сотрудников в определенном департаменте (department) в определенной должности (position).
1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
task0237
Напиши запрос, который согласно данных из таблицы cars выберет поля name и prod_year. В итоговой выборке информация должна быть сгрупирована по колонкам name, prod_year и price.
1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
task0238
Напиши запрос, который из таблицы employee на основе даты рождения (date_of_birth) выберет год и месяц (номер) рождения каждого сотрудника. Год и месяц нужно выбрать в разные колонки.
1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
task0239
Напиши запрос, который из таблицы employee на основе даты рождения (date_of_birth) выберет год и месяц (номер) рождения сотрудников, рожденных зимой. Год и месяц нужно выбрать в разные колонки.
1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
task0240
Заказчик считает, что старшие сотрудники более опытные. Напиши запрос, который из таблицы employee на основе года из даты рождения (date_of_birth) выберет в первую колонку 'yes', если год меньше 2000 и 'no' в противном случае.
1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
task0241
Напиши запрос, который из таблицы employee на основе даты рождения (date_of_birth) выберет год и месяц (номер) рождения каждого сотрудника. Год и месяц нужно выбрать в разные колонки. Сгруппируй данные по году и месяцу.
1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
task0242
Напиши запрос, который из таблицы employee на основе даты рождения (date_of_birth) выберет год, месяц (номер) рождения и количество сотрудников, родившихся в этот год и месяц. Год и месяц нужно выбрать в разные колонки.
1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
task0243
Напиши запрос, который из таблицы cars на основе даты производства (prod_date) выберет год, месяц (номер) производства и количество автомобилей, произведенных в этот год и месяц. Год и месяц нужно выбрать в разные колонки. Колонкам год и месяц присвой алиасы prod_year и prod_month соответственно. Гр
1
Задача
Модуль 4. Работа с БД,  2 уровень3 лекция
Недоступна
Только черные
Напиши запрос, который из таблицы cars на основе даты производства (prod_date) выберет год, месяц (номер) производства и количество автомобилей, произведенных в этот год и месяц. Год и месяц нужно выбрать в разные колонки. Колонкам год и месяц присвой алиасы prod_year и prod_month соответственно.
Комментарии (19)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Артём
Уровень 112
28 мая 2025, 13:14
В task0232 в условии задачи в колонке is_full_time предполагаются строковые значения, а в таблице init_data.sql заданы целочисленные.
Максим
Уровень 71
21 сентября 2025, 18:00
Я тоже офигел... Скорее всего сломаная задача....
fxtort Java Developer
14 октября 2024, 14:23
почему у меня не работал скрипт и мне пришлось так этот менять? пишу в mySQL server
-- SQL & Hibernate
-- 2 уровень, 4 лекция
USE TestOrDelete;

CREATE TABLE furnitureDate1 (
id INT IDENTITY(1,1) PRIMARY KEY,
name NVARCHAR(255),
brand NVARCHAR(255),
price DECIMAL(10,2),
count INT,
join_date DATE
);

INSERT INTO furnitureDate1
(name, brand, price, count, join_date)
VALUES
('Стол', NULL, 20.00, 15, '2012-06-30'),
('Стул', NULL, 5.00, 45, '2013-08-12'),
('Диван', 'IKEA', 80.00, 10, '2014-01-01'),
('Кровать', 'IKEA', 75.00, 10, '2015-05-12'),
('Шкаф', 'Bosh', 125.00, 15, '2015-10-10'),
('Полка', 'OBI', 25.00, 114, '2018-11-11'),
('Телевизор', 'LG', 350.00, 4, NULL),
('Лампа', 'LG', 15.00, 100, NULL),
('Комод', 'LG', 350.00, 5, NULL),
('Телевизор', 'IKEA', 99.00, 10, NULL),
('Плита', 'Bosh', 199.00, 10, NULL);

SELECT * FROM furnitureDate1;

SELECT
    YEAR(join_date) AS join_year,
    MONTH(join_date) AS join_month,
    join_date
FROM
    furnitureDate1
WHERE
    join_date IS NOT NULL
GROUP BY
    YEAR(join_date), MONTH(join_date), join_date
ORDER BY
    join_year, join_month
Pavlo PlynkoJava-разработчик в CodeGymExpert
5 декабря 2024, 21:24
Т.е. это уже рабочий вариант? А какой тогда был не рабочий? И что именно пришлось менять?
Олег
Уровень 106
Expert
17 сентября 2024, 19:51
Щёлкнул
Виталий
Уровень 115
Expert
18 июля 2024, 19:41
Чтож? Теперь я в совершенстве могу слепым методом печатать слова employee, department, position... Спасибо, джавараш!
Олег
Уровень 109
Expert
21 июня 2024, 08:11
в 0241 Валик не пропускает если использовать пробел в коде между YEAR и (date_of_birth)
Данила
Уровень 111
Expert
15 ноября 2023, 17:42
Задача 41 и 42 одинаково решается, условие немножко перефразированно
Anonymous #2879919
Уровень 10
30 сентября 2023, 17:25
всем привет! Скажите пжл есть ли возможность решать задачи или дана только теория_?
Александр
Уровень 2
9 ноября 2023, 18:50
Вроде бы с подпиской JavaRush Университет появляются задачи
Madina Baizhanova
Уровень 29
23 августа 2023, 10:12
Руслан
Уровень 79
Expert
11 декабря 2022, 15:00
странно что валидатор не пропускает если группировка года происходит по указанному новому имени через as
aDuVaN4Ik
Уровень 42
2 января 2023, 13:08
Как открыть задачки?
Ramazan
Уровень 36
Expert
12 января 2023, 17:31
Тоже интересно, разве в этом квесте есть задачи?
aDuVaN4Ik
Уровень 42
13 января 2023, 18:20
Они есть. Но они только для учеников университета от JR
Ramazan
Уровень 36
Expert
13 января 2023, 21:17
Да, уже нашел ответ тоже, спасибо!)
Александр
Уровень 111
Expert
20 ноября 2022, 09:37
Последняя задачка понравилась. task 0240 частично не мог понять условие самой задачи. Все время забываю, что при выборке мы IF ставим в самое начало.
Марат Гарипов
Уровень 108
Expert
29 декабря 2022, 20:27
я поставил if перед select и сработало)
Ольга
Уровень 72
Expert
23 мая 2024, 11:39
Я без ифа вот так сделала where name like '%Black Car%' and price > 99000