/ MySql

Как сравнивать даты в MySQL

MySQL предоставляет возможность сравнивать различные даты между собой, или с каким-то определенным выражением. В этой статье мы обсудим, как работать с датой в Mysql, как из сравнивать и строить запросы с учетом дат.

Когда вам нужно сравнить дату какого-то столбца с произвольной датой, вы можете использовать функцию DATE(), которая извлекает дату из переданного аргумента (без учета времени) и сравнить ее со строкой нужной вам даты.

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

Например, предположим, что у вас есть таблица MySQL под названием users со следующими строками:

mysql> SELECT * FROM users;
+---------+------------+-----------+---------------------+
| user_id | first_name | last_name | last_update         |
+---------+------------+-----------+---------------------+
|     201 | Peter      | Parker    | 2021-08-01 16:15:00 |
|     202 | Thor       | Odinson   | 2021-08-02 12:15:00 |
|     204 | Loki       | Laufeyson | 2021-08-03 10:43:24 |
+---------+------------+-----------+---------------------+
3 rows in set (0.00 sec)

Теперь вам нужно выбрать все строки из таблицы users, у которых значение last_update больше 2021-08-01.

И это достаточно просто сделать:

SELECT 
    user_id,
    first_name,
    last_name,
    last_update
FROM 
    users
WHERE 
    DATE(last_update) > "2021-08-01"
ORDER BY 
    last_update ASC

Результат запроса выше будет следующим:

+---------+------------+-----------+---------------------+
| user_id | first_name | last_name | last_update         |
+---------+------------+-----------+---------------------+
|     202 | Thor       | Odinson   | 2021-08-02 12:15:00 |
|     204 | Loki       | Laufeyson | 2021-08-03 10:43:24 |
+---------+------------+-----------+---------------------+
2 rows in set (0.00 sec)

При сравнении столбца типа DATETIME или TIMESTAMP с датой в виде строки (как в запросе выше), MySQL автоматически преобразует значения к единому формату для сравнения и веронет подходящзие результаты.

Чтобы проверить результат запроса добавим оператор ORDER BY в приведенный выше запрос.

Вы можете сразу определить, удовлетворяет ли запрос вашему требованию, взглянув на первую строку. Как и в приведенном выше примере, самое раннее значение столбца last_update должно быть 2021-08-02.

Вы также можете использовать оператор BETWEEN, чтобы выбрать все строки, в которых столбец даты находится между двумя указанными выражениями даты:

SELECT 
    user_id,
    first_name,
    last_name,
    last_update
FROM 
    users
WHERE 
    BETWEEN "2021-08-01" AND "2021-08-02"
ORDER BY 
    last_update ASC

Приведенный выше запрос выведет следующий результат:

+---------+------------+-----------+---------------------+
| user_id | first_name | last_name | last_update         |
+---------+------------+-----------+---------------------+
|     201 | Peter      | Parker    | 2021-08-01 16:15:00 |
|     202 | Thor       | Odinson   | 2021-08-02 12:15:00 |
+---------+------------+-----------+---------------------+
2 rows in set (0.00 sec)

НО! MySQL допускает только один формат даты: yyyy-mm-dd, поэтому вам нужно форматировать любое строковое выражение даты по которым вы хотите выбирать данные к нужному формату.

Зачем использовать функцию DATE() для сравнения дат

Функция MySQL DATE() извлекает часть даты из столбца DATETIME или TIMESTAMP и приводит её к формату строки, как показано ниже:

mysql> SELECT DATE('2005-08-28 01:02:03');
-> '2005-08-28'

Эта функция используется для того, чтобы MySQL использовал для сравнения только часть даты вашего столбца, без учета времени.

Если не использовать функцию DATE(), то MySQL также будет сравнивать и время столбца с вашим строковым выражением. Таким образом, результатом будут записи, полностью совпадаюащие до секунды.

Возвращаясь к приведенному выше примеру таблицы, следующий запрос:

SELECT 
    user_id,
    first_name,
    last_name,
    last_update
FROM 
    users
WHERE 
    last_update > "2021-08-01"
ORDER BY 
    last_update ASC

Вернет такие результаты:

+---------+------------+-----------+---------------------+
| user_id | first_name | last_name | last_update         |
+---------+------------+-----------+---------------------+
|     201 | Peter      | Parker    | 2021-08-01 16:15:00 |
|     202 | Thor       | Odinson   | 2021-08-02 12:15:00 |
|     204 | Loki       | Laufeyson | 2021-08-03 10:43:24 |
+---------+------------+-----------+---------------------+
3 rows in set (0.01 sec)

Как видно из результатов, условие сравнения last_update > "2021-08-01" становится last_update > "2021-08-01 00:00:00", и MySQL возвращает соответствующий набор результатов.

Если вы собираетесь сравнивать записи включая время, то вам нужно добавить часть времени в ваше строковое выражение.

Следующий запрос из той же таблицы:

SELECT 
    user_id,
    first_name,
    last_name,
    last_update
FROM 
    users
WHERE 
    last_update > "2021-08-01 20:00:00"
ORDER BY 
    last_update ASC

Даст следующий результат:

+---------+------------+-----------+---------------------+
| user_id | first_name | last_name | last_update         |
+---------+------------+-----------+---------------------+
|     202 | Thor       | Odinson   | 2021-08-02 12:15:00 |
|     204 | Loki       | Laufeyson | 2021-08-03 10:43:24 |
+---------+------------+-----------+---------------------+
2 rows in set (0.00 sec)

Сравнение дат между двумя столбцами дат

Если у вас уже есть два столбца даты, то вы можете сразу же сравнить их с помощью операторов <, <=, =, >=, > или BETWEEN.

Предположим, что в вашей таблице есть столбцы last_update и last_login, как показано ниже:

+---------+------------+-----------+---------------------+---------------------+
| user_id | first_name | last_name | last_update         | last_login          |
+---------+------------+-----------+---------------------+---------------------+
|     201 | Peter      | Parker    | 2021-08-01 16:15:00 | 2021-08-17 10:00:00 |
|     202 | Thor       | Odinson   | 2021-08-02 12:15:00 | 2021-08-02 08:00:00 |
|     204 | Loki       | Laufeyson | 2021-08-03 10:43:24 | 2021-08-10 06:00:00 |
+---------+------------+-----------+---------------------+---------------------+

Чтобы получить все строки, в которых столбец last_login находится позже столбца last_update, вы можете использовать следующий запрос:

SELECT 
    user_id,
    first_name,
    last_name,
    last_update
FROM 
    users
WHERE 
    last_login > last_update
ORDER BY 
    last_update ASC

Результат будет следующим:

+---------+------------+-----------+---------------------+---------------------+
| user_id | first_name | last_name | last_update         | last_login          |
+---------+------------+-----------+---------------------+---------------------+
|     204 | Loki       | Laufeyson | 2021-08-03 10:43:24 | 2021-08-10 06:00:00 |
|     201 | Peter      | Parker    | 2021-08-01 16:15:00 | 2021-08-17 10:00:00 |
+---------+------------+-----------+---------------------+---------------------+
2 rows in set (0.00 sec)

Вот каким образом вы можете выполнять сравнение дат в MySQL.

Не забудьте, что вам нужно иметь строковое выражение даты, отформатированное как yyyy-mm-dd или yyyy-mm-dd hh:mm:ss, если вы хотите сравнить и временную часть.

Выбор дат за определнный интервал

Очень часто приходится выбирать записи с датой за определнный интервал. Для этих целей в MySql существуют встроенная функции INTERVAL, упрощающая работу с датами за определенный период.

Например, для того, чтобы выбрать записи, обновленные за последний год, выполним запрос:

SELECT
    user_id,
    first_name,
    last_name,
    last_update
FROM
    users
WHERE
    last_login > CURDATE() - INTERVAL 1 YEAR
ORDER BY
    last_update ASC

При том, что INTERVAL может работать с различными интервалами времени:

  • SECOND - секунды
  • MINUTE - минуты
  • HOUR - часы
  • DAY - дни
  • MONTH - месяцы
  • YEAR - года

Те же самые действия применимы и к UPDATE-операциям:

UPDATE 
    users
SET 
    last_update = CURDATE() - INTERVAL 10 DAY
WHERE
    id = 1

Резюме

В этой статье поговорили про работу с датами в Mysql. Как можно выбрать даты определенной даты, или по указанному интервалу. А так же, как работать с колонками дат разных типов.

Если вы хотите поупражняться с запросами, то вот вам демонстрационная таблица:

CREATE TABLE `users` (
  `user_id` smallint unsigned NOT NULL AUTO_INCREMENT,
  `first_name` varchar(45) NOT NULL,
  `last_name` varchar(45) NOT NULL,
  `last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `last_login` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `users` (`user_id`, `first_name`, `last_name`, `last_update`, `last_login`)
VALUES
	(201,'Peter','Parker','2021-08-01 16:15:00','2021-08-17 10:00:00'),
	(202,'Thor','Odinson','2021-08-02 12:15:00','2021-08-02 08:00:00'),
	(204,'Loki','Laufeyson','2021-08-03 10:43:24','2021-08-10 06:00:00');