У меня есть таблица в MySQL, которая содержит строки дней от 1 до 7 (с понедельника по воскресенье), я хочу получить полную неделю строк от 1 до 7 на основе определенной даты, дата в некоторых строках равна нулю, а в некоторых установлена. строки:
я хотел бы выбрать неделю, и она должна включать конкретную дату, поэтому, например, выбор недели на основе 29 мая 2024 г. должен дать мне следующий результат:
и если выбрать дату, которая не существует, например 05.05.2024, она должна дать мне:
возможно ли это сделать с помощью одного запроса? иначе как бы вы сделали что-то подобное? Спасибо
изменить: я использую Mysql версии 8.0
MySQL версия 8.0
Если в неделе больше дат (с допустимой датой), выберете ли вы только 1, но ожидаете, что получите 2?






Группируйте по 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).
Учитывая ваш образец данных плюс
Вы можете получить всю дату недели 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;
Выходы:
Вот 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;
Выходы:
Вот еще одна db<>рабочий пример.
Какая у вас версия MySQL?