JavaRush/Курсы/Модуль 4. Работа с БД/Функции работы с датой, практические примеры

Функции работы с датой, практические примеры

Открыта

Ищем события за последние 30 дней

Еще одна часто возникающая задача – это поиск строк, которые относятся к определенному диапазону дат. В принципе в этом нет ничего сложного, если начальная и конечная даты диапазона фиксированы: SQL умеет сравнивать даты так же хорошо, как и числа.

К датам можно применять операторы сравнения: <, >, <= и т. п. Кроме того, есть специальный оператор BETWEEN, который тоже умеет работать с датами. Давай для примера напишем запрос, который отберет все задачи из таблицы task, которые нужно сделать летом 2022 года. Запрос будет выглядеть так:

SELECT * FROM task WHERE task.deadline BETWEEN '2022-06-01' AND '2022-08-31'

Результат этого запроса будет таким:

id emploee_id name deadline
1 1 Исправить багу на фронтенде 2022-06-01
2 2 Исправить багу на бэкенде 2022-06-15
3 5 Купить кофе 2022-07-01
4 5 Купить кофе 2022-08-01

Но что писать в запросе, если мы хотим получить задачи, например, за последние 30 дней. Где последние 30 дней прямо привязаны ко времени выполнения запроса. То есть если запрос выполняется 25 июля, то нужно выбрать даты с 25 июня по 24 июля. Как привязать интервал дат к текущему времени?

Для этого нужно воспользоваться функцией сложения дат:

DATE_ADD (дата, INTERVAL выражение единицы)

Думаю, легче будет объяснить с помощью нескольких примеров:

# Запрос Результат
1 DATE_ADD('2022-06-04', INTERVAL 5 DAY) 2022-06-09
2 DATE_ADD('2022-06-04', INTERVAL 4 WEEK) 2022-07-02
3 DATE_ADD('2022-06-04', INTERVAL 2 MONTH) 2022-08-04
4 DATE_SUB('2022-06-04', INTERVAL 5 DAY) 2022-05-30
5 DATE_SUB('2022-06-04', INTERVAL 4 WEEK) 2022-05-07
6 DATE_SUB('2022-06-04', INTERVAL 2 MONTH) 2022-04-04

Кстати, из определенной даты можно так же вычитать определенное количество дней, недель, месяцев и лет.

И если вернуться к нашему запросу – получить данные за последние 30 дней, то нам нужны две даты этого диапазона:

  • CURDATE() – конец диапазона
  • DATE_SUB( CURDATE() , INTERVAL 30 DAY) – начало диапазона

Запрос будет выглядеть так:

SELECT * FROM task WHERE task.deadline  BETWEEN DATE_SUB( CURDATE() , INTERVAL 30 DAY) AND CURDATE() 

Результат этого запроса будет таким (у меня сегодня 4 июня 2022 года):

id emploee_id name deadline
1 1 Исправить багу на фронтенде 2022-06-01

Как найти разницу между двумя датами

И еще одна полезная функция. Иногда может понадобиться вычислить разницу между двумя датами в днях. Для этого у SQL есть специальная функция – DATEDIFF().

Работать с ней очень просто:

DATEDIFF (дата1, дата2)

Из первой даты просто вычитается вторая. Если дата2 идет после дата1, то результат будет отрицательным.

Кстати, мы можем переписать наш предыдущий запрос, используя функцию DATEDIFF(). Нам нужно отобрать все задачи из таблицы task, дедлайн которых отличается от текущей даты не более чем на 30 дней. Вот как будет выглядеть этот запрос:

SELECT * FROM task WHERE DATEDIFF(task.deadline, CURDATE() ) < 30 AND DATEDIFF(task.deadline, CURDATE() ) > -30

Результат этого запроса будет таким (у меня сегодня 4 июня 2022 года):

id emploee_id name deadline
1 1 Исправить багу на фронтенде 2022-06-01
2 2 Исправить багу на бэкенде 2022-06-15
3 5 Купить кофе 2022-07-01

В этот раз SQL нашел целых три строки. Подумай, почему в прошлый раз была одна строка, а в этот раз – три?

1
Задача
Модуль 4. Работа с БД,  4 уровень3 лекция
Недоступна
События за последние 20 дней
События за последние 20 дней
1
Задача
Модуль 4. Работа с БД,  4 уровень3 лекция
Недоступна
События за текущий месяц
События за текущий месяц
1
Задача
Модуль 4. Работа с БД,  4 уровень3 лекция
Недоступна
События за последние 2 недели
События за последние 2 недели
1
Задача
Модуль 4. Работа с БД,  4 уровень3 лекция
Недоступна
Более 5 событий в день
Более 5 событий в день
1
Задача
Модуль 4. Работа с БД,  4 уровень3 лекция
Недоступна
День регистраций
День регистраций
1
Задача
Модуль 4. Работа с БД,  4 уровень3 лекция
Недоступна
Самый неудачный месяц
Самый неудачный месяц
1
Задача
Модуль 4. Работа с БД,  4 уровень3 лекция
Недоступна
Пользователь решает задачи
Пользователь решает задачи
Комментарии (23)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Артём
Уровень 112
14 июня 2025, 23:46
В task0428 в init_data.sql используется диалект, отличный от MySQL. Чтобы всё заработало, надо поменять DATEADD(DAY, -1, CURRENT_DATE()) на DATE_ADD(CURDATE(), INTERVAL -1 DAY) в первой строке списка рядов. В остальных строках поменять так же, подставляя нужный интервал.
Александр
Уровень 115
22 февраля 2025, 22:41
/* Комментарий удален */
Булат
Уровень 109
19 февраля 2025, 20:08
здесь прям посложнее задачки, участвуют предыдущие лекции
I'm Siberian Trust me, i'm an engineer Expert
15 января 2025, 12:54
исправленная табличка для тех, кто делает из идеи с базой mysql: Не забываем менять название колонки на нужное к текущей задаче date, date_time и т.д https://pastebin.com/vbCn6fwM
Николай
Уровень 109
15 января 2025, 13:24
<3
Yaroslav
Уровень 109
Expert
19 июля 2024, 22:46
Кто будет задаваться вопросом "Почему в прошлый раз была одна строка, а в этот раз – три?", потому что -30 < (-11, -27) < 30
Руслан
Уровень 115
24 июня 2024, 09:58
Создание баз данных 'event' не работает
Виталий
Уровень 107
Expert
7 ноября 2023, 12:59
У вас пример прошлогодний )0)
Anonymous #3322801
Уровень 5
Expert
25 октября 2023, 16:28
Задачи понравились, но опять же есть что доработать. Как минимум предоставляемую таблицу и задание под нее. Очень часто имена колонок в таблице и в задании отличаются.
Igor K
Уровень 1
5 октября 2023, 11:01
Поддерживаю , не работает ни хрена
MrFurion
Уровень 32
27 августа 2023, 20:00
можно писать запросы так как они выглядят в джава коде а не как в голову пришлось БРЕД