Оптимизируйте использование оператора CASE в MySQL

Всем привет,

У меня есть таблица, как показано на скриншоте выше. Я написал запрос, используя оператор CASE, чтобы он возвращал дополнительные столбцы, которые мне нужны. Ниже приведен запрос, который я написал:

SELECT 
    *,
    CASE WHEN (SUM(CASE WHEN class = 'class 1' THEN 1 END) OVER(PARTITION BY student_id)) >= 1 THEN 1 ELSE 0  END AS 'Class 1',
    CASE WHEN (SUM(CASE WHEN class = 'class 2' THEN 1 END) OVER(PARTITION BY student_id)) >= 1 THEN 1 ELSE 0  END AS 'Class 2',
    CASE WHEN (SUM(CASE WHEN class = 'class 3' THEN 1 END) OVER(PARTITION BY student_id)) >= 1 THEN 1 ELSE 0  END AS 'Class 3',
    CASE WHEN (SUM(CASE WHEN class = 'class 4' THEN 1 END) OVER(PARTITION BY student_id)) >= 1 THEN 1 ELSE 0  END AS 'Class 4'
FROM qa;

Это таблица результатов, которую я получаю:

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

Например, учащийся с student_id2 посещал class 1, поэтому в столбце Class 1 обе строки для student_id2 будут отображаться 1.

Я уже добился того, чего хочу в своем запросе, но сейчас вместо использования 1 я хочу, чтобы это был enrollment_date класса. Ниже приведен окончательный результат, который я хочу:

Могу ли я узнать, как мне изменить свой запрос, чтобы получить окончательный результат на скриншоте выше?

2-й вопрос:

Как вы можете видеть в моем запросе выше, каждый класс имеет один оператор CASE соответственно, чтобы создать столбец для класса. Однако в будущем могут быть классы 5,6,7,..., поэтому мне нужно снова добавить дополнительный оператор CASE всякий раз, когда существует другой новый класс. В любом случае, я могу оптимизировать свой запрос, чтобы не было необходимости иметь 4 оператора CASE для 4 разных классов, и все же я мог создавать столбцы для разных классов (когда есть новый класс, будет новый столбец для класса также)?

Образец данных

create table qa(
    student_id INT,
    class varchar(20),
    class_end_date date,
    enrollment_date date
);

insert into qa (student_id, class, class_end_date, enrollment_date) 
values 
(1, 'class 1', '2022-03-03', '2022-02-14'),
(1, 'class 3', '2022-06-13', '2022-04-12'),
(1, 'class 4', '2022-07-03', '2022-06-19'),
(2, 'class 1', '2023-03-03', '2022-07-14'),
(2, 'class 2', '2022-08-03', '2022-07-17'),
(4, 'class 4', '2023-03-03', '2022-012-14'),
(4, 'class 2', '2022-04-03', '2022-03-21')
;

Извините, я забыл прикрепить образцы данных. Я отредактировал свой вопрос с запросом, чтобы создать образец таблицы и данных, спасибо.

weizer 25.11.2022 13:34

Зачем вам повторяющиеся строки? Конечно, вам нужна только одна строка для каждого ученика? Я предлагаю вам заменить все изображения данных в вашем вопросе таблицами уценки.

user1191247 25.11.2022 13:41

На самом деле это не повторяющиеся строки, потому что class_end_date все еще разные.

weizer 25.11.2022 13:45

Разве это не противоречит смыслу изменения даты зачисления?

user1191247 25.11.2022 13:47

Так что на самом деле мой план таков: после того, как у меня будет 4 столбца с датой зачисления для каждого класса, я буду использовать эти 4 столбца за вычетом столбца class_end_date, чтобы найти количество дней между датой зачисления для каждого класса и class_end_date.

weizer 25.11.2022 14:00

Возможно, у вас есть лучший способ сделать это, но это то, о чем я могу думать до сих пор, все еще новичок в MYSQL, спасибо!

weizer 25.11.2022 14:01
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
7
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вот пример со сводными значениями class_end_date и enrollment_date:

SELECT 
    student_id,
    GROUP_CONCAT(IF(class = 'class 1', enrollment_date, null)) 'Class 1 Enrolled',
    GROUP_CONCAT(IF(class = 'class 1', class_end_date, null)) 'Class 1 End',
    GROUP_CONCAT(IF(class = 'class 2', enrollment_date, null)) 'Class 2 Enrolled',
    GROUP_CONCAT(IF(class = 'class 2', class_end_date, null)) 'Class 2 End',
    GROUP_CONCAT(IF(class = 'class 3', enrollment_date, null)) 'Class 3 Enrolled',
    GROUP_CONCAT(IF(class = 'class 3', class_end_date, null)) 'Class 3 End',
    GROUP_CONCAT(IF(class = 'class 4', enrollment_date, null)) 'Class 4 Enrolled',
    GROUP_CONCAT(IF(class = 'class 4', class_end_date, null)) 'Class 4 End'
FROM qa
GROUP BY student_id;

См. Pivot для хранимой процедуры, которая будет генерировать и [необязательно] выполнять запрос на основе определения таблицы и данных.

Другие вопросы по теме