MySQL: cравнение даты (datetime) через оператор BETWEEN

Блог Никиты Синицы


MySQL: cравнение даты (datetime) через оператор BETWEEN

2017-01-01 15:33:19

Оператор BETWEEN идеально подходит для сравнения диапазона между датами (datetime). Но тут есть подводные камни. Например, есть задача — выбрать данные из таблицы за некоторый промежуток времени (с ‘2008-08-14’ по ‘2008-08-23’).

Рекомендации:
1. Выполняя любые сравнения, приводить все данные к одному типу.
2. Если один операнд имеет значение типа TIMESTAMP или DATETIME, а другой является константой, операнды сравниваются как значения типа TIMESTAMP. А это значит, что если была строка в виде ‘2008-08-14’, то она автоматически преобразуется в TIMESTAMP ‘2008-08-14 00:00:00’ и это влияет на результат запроса.
3. Над данными, которые участвуют в условиях сравнения желательно не делать никаких операций — это позволяет для них использовать индексы, иначе они игнорируются.


Примеры запросов с BETWEEN и без него:

# Поле created_at - тип DATETIME
# КОРРЕКТНЫЕ ЗАПРОСЫ

# 1: Индексы для created_at поля не используются. 
# Условие BETWEEN '2008-08-14' AND '2008-08-23' 
# преобразуется в BETWEEN '2008-08-14 00:00:00' AND '2008-08-23 00:00:00'.
SELECT * FROM news
  WHERE DATE(created_at) BETWEEN '2008-08-14' AND '2008-08-23';

# 2: Оператор BETWEEN не используем, но тоже не самый лучший вариант, индексы не используются
SELECT * FROM news
  WHERE DATE(created_at) >= '2008-08-14' AND DATE(created_at) <= '2008-08-23';

# 3: Строки '2008-08-14 00:00:00' и '2008-08-23 23:59:59' не приведены к типу данных DATE
SELECT * FROM news
  WHERE created_at BETWEEN '2008-08-14 00:00:00' AND '2008-08-23 23:59:59';

# 4: Самый лучший вариант, привели к типу DATETIME, индексы будут использоваться
SELECT * FROM news
  WHERE created_at BETWEEN STR_TO_DATE('2008-08-14 00:00:00', '%Y-%m-%d %H:%i:%s') 
  AND STR_TO_DATE('2008-08-23 23:59:59', '%Y-%m-%d %H:%i:%s');


#############################
# НЕПРАВИЛЬНЫЕ ЗАПРОСЫ

# 5: Строки '2008-08-14' и '2008-08-23' преобразуются в TIMESTAMP и дополняются '00:00:00'
SELECT * FROM news 
  WHERE created_at >= '2008-08-14' AND created_at <= '2008-08-23';

# 6: Аналогично запросу 5
SELECT * FROM news 
  WHERE created_at BETWEEN STR_TO_DATE('2008-08-14', '%Y-%m-%d') AND STR_TO_DATE('2008-08-23', '%Y-%m-%d');

Получаем самый лучший запрос:

SELECT * FROM news
  WHERE created_at BETWEEN STR_TO_DATE('2008-08-14 00:00:00', '%Y-%m-%d %H:%i:%s') 
  AND STR_TO_DATE('2008-08-23 23:59:59', '%Y-%m-%d %H:%i:%s');

Ссылки по теме:
MySQL 5.1 Reference Manual :: 11.2.3 Comparison Functions and Operators :: Operator BETWEEN
MySQL 5.1 Reference Manual :: 11 Functions and Operators :: 11.6 Date and Time Functions
Search by Date or Timestamp in MySQL

Источник: tigor.com.ua




Добавить комментарий:













Смотрите также:

Simple HTML DOM: взять атрибут data-src
Иконки для сайтов
PHP: отнять от даты один год
PHP: взять из строки только латиницу
Таблица нулевых вилок
Что такое МОС в Sape
Заменить <br/> на \n
Mysql: добавить уникальный индекс для столбца типа text
Бесплатная проверка «Ping» из различных частей мира
PHP: взять все ссылки
PHP: обрезать строку до определенного символа
Php: превью новости (оставить энное количество символов)
Php: взять информацию из тэга
PHP: вырезать из строки тэг img
Включить показ предупреждений и ошибок PHP
В Испании создали очки для селфи
Продажи Apple Watch рухнули на 55%
«ВКонтакте» вернула функцию граффити
Facebook разрешил пользователям сохранять видео на смартфоны
Microsoft признала провал Windows10
"Яндекс" рассказал тонкости построения мобильного раздела на поддомене
Debian mysql restart
Как удалить в Dreamweaver разный кусок кода во всех файлах
Бесплатная проверка битых ссылок
Декодер кодировок