Как я могу выбрать, какая строка выбрана при использовании OR в Mysql

У меня есть таблица в MySQL, которая содержит строки дней от 1 до 7 (с понедельника по воскресенье), я хочу получить полную неделю строк от 1 до 7 на основе определенной даты, дата в некоторых строках равна нулю, а в некоторых установлена. строки:

идентификатор день дата 1 1 НУЛЕВОЙ 2 2 НУЛЕВОЙ 3 3 НУЛЕВОЙ 4 4 НУЛЕВОЙ 5 5 НУЛЕВОЙ 6 6 НУЛЕВОЙ 7 7 НУЛЕВОЙ 8 3 2024-05-29

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

идентификатор день дата 1 1 НУЛЕВОЙ 2 2 НУЛЕВОЙ 8 3 2024-05-29 4 4 НУЛЕВОЙ 5 5 НУЛЕВОЙ 6 6 НУЛЕВОЙ 7 7 НУЛЕВОЙ

и если выбрать дату, которая не существует, например 05.05.2024, она должна дать мне:

идентификатор день дата 1 1 НУЛЕВОЙ 2 2 НУЛЕВОЙ 3 3 НУЛЕВОЙ 4 4 НУЛЕВОЙ 5 5 НУЛЕВОЙ 6 6 НУЛЕВОЙ 7 7 НУЛЕВОЙ

возможно ли это сделать с помощью одного запроса? иначе как бы вы сделали что-то подобное? Спасибо

изменить: я использую Mysql версии 8.0

Какая у вас версия MySQL?

JNevill 04.06.2024 21:59

MySQL версия 8.0

Black Iso 04.06.2024 22:03

Если в неделе больше дат (с допустимой датой), выберете ли вы только 1, но ожидаете, что получите 2?

P.Salmon 05.06.2024 10:02
Освоение архитектуры микросервисов с 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
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
3
61
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Группируйте по day, используйте условие для возврата NULL, если столбец date не соответствует заданной дате, в противном случае столбец date. Затем используйте MAX(), чтобы предпочесть эту строку.

SELECT day, MAX(IF(WEEKDAY('2024-05-29')+1 = day, date, NULL)) AS date
FROM dates
GROUP BY day;

SELECT day, MAX(IF(WEEKDAY('2024-05-05')+1 = day, date, NULL)) AS date
FROM dates
GROUP BY day;
Ответ принят как подходящий

Вот запрос, который я придумал, который работает именно так, как я хотел. Если у кого-нибудь есть какие-либо замечания о том, как оптимизировать это или любое другое решение, я хотел бы их услышать:

SELECT s1.* FROM my_table as s1 INNER JOIN ( SELECT day, MAX(date) as date_max FROM my_table WHERE my_table.date = '2024-06-29' OR my_table.date is null GROUP BY my_table.day ) as s2 ON s1.day = s2.day AND ( s1.date = s2.date_max or ( s1.date IS NULL AND s2.date_max IS NULL ) ) ORDER BY day ASC

Пожалуйста, отформатируйте запрос в несколько строк, чтобы его было легче читать. Вы можете очистить критерии соединения, используя <=> (безопасное значение NULL).

user1191247 05.06.2024 10:24

Учитывая ваш образец данных плюс

идентификатор день дата 9 5 2024-05-31

Вы можете получить всю дату недели NULL и использовать ее для LEFT JOIN на основе переданной даты:

SELECT
    COALESCE(t2.id, t1.id) AS id,
    t1.day,
    t2.date
FROM my_table t1
LEFT JOIN my_table t2 ON t1.day = t2.day AND t2.date = '2024-05-29'
WHERE t1.date IS NULL;

Выходы:

идентификатор день дата 1 1 нулевой 2 2 нулевой 8 3 2024-05-29 4 4 нулевой 5 5 нулевой 6 6 нулевой 7 7 нулевой

Вот db<>рабочий пример.

Этот запрос выиграет от индекса (date, day).

Если вы хотите вернуть все совпадающие даты для недели с введенной датой, как предложено P.Salmon в комментариях, вы можете сделать:

SELECT
    COALESCE(t2.id, t1.id) AS id,
    t1.day,
    t2.date
FROM (
    SELECT id, day, '2024-05-29' - INTERVAL (WEEKDAY('2024-05-29') + 1 - t.day) DAY AS date
    FROM my_table t
    WHERE t.date IS NULL
) AS t1
LEFT JOIN my_table t2 ON t1.day = t2.day AND t1.date = t2.date;

Выходы:

идентификатор день дата 1 1 нулевой 2 2 нулевой 8 3 2024-05-29 4 4 нулевой 9 5 2024-05-31 6 6 нулевой 7 7 нулевой

Вот еще одна db<>рабочий пример.

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