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

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

Модуль 4. Работа с БД
2 уровень , 3 лекция
Открыта

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
В task0232 в условии задачи в колонке is_full_time предполагаются строковые значения, а в таблице init_data.sql заданы целочисленные.
Максим Уровень 69
21 сентября 2025
Я тоже офигел... Скорее всего сломаная задача....
fxtort Уровень 6
14 октября 2024
почему у меня не работал скрипт и мне пришлось так этот менять? пишу в 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 Plynko Уровень 1 Expert
5 декабря 2024
Т.е. это уже рабочий вариант? А какой тогда был не рабочий? И что именно пришлось менять?
Олег Уровень 106 Expert
17 сентября 2024
Щёлкнул
Виталий Уровень 115 Expert
18 июля 2024
Чтож? Теперь я в совершенстве могу слепым методом печатать слова employee, department, position... Спасибо, джавараш!
Олег Уровень 109 Expert
21 июня 2024
в 0241 Валик не пропускает если использовать пробел в коде между YEAR и (date_of_birth)
Данила Уровень 111 Expert
15 ноября 2023
Задача 41 и 42 одинаково решается, условие немножко перефразированно
Anonymous #2879919 Уровень 10
30 сентября 2023
всем привет! Скажите пжл есть ли возможность решать задачи или дана только теория_?
Александр Уровень 2
9 ноября 2023
Вроде бы с подпиской JavaRush Университет появляются задачи
Madina Baizhanova Уровень 29
23 августа 2023
Руслан Уровень 79 Expert
11 декабря 2022
странно что валидатор не пропускает если группировка года происходит по указанному новому имени через as
aDuVaN4Ik Уровень 42
2 января 2023
Как открыть задачки?
Ramazan Уровень 36 Expert
12 января 2023
Тоже интересно, разве в этом квесте есть задачи?
aDuVaN4Ik Уровень 42
13 января 2023
Они есть. Но они только для учеников университета от JR
Ramazan Уровень 36 Expert
13 января 2023
Да, уже нашел ответ тоже, спасибо!)
Александр Уровень 111 Expert
20 ноября 2022
Последняя задачка понравилась. task 0240 частично не мог понять условие самой задачи. Все время забываю, что при выборке мы IF ставим в самое начало.
Марат Гарипов Уровень 108 Expert
29 декабря 2022
я поставил if перед select и сработало)
Ольга Уровень 72 Expert
23 мая 2024
Я без ифа вот так сделала where name like '%Black Car%' and price > 99000