MySQL сравнивает строку DATE со строкой из поля DATETIME

93

У меня вопрос: можно ли сделать выбор из базы данных MySQL, сравнив одну строку DATE «2010-04-29» со строками, которые хранятся как DATETIME (2010-04-29 10:00)?

У меня есть одно средство выбора даты, которое фильтрует данные, и я хотел бы запросить таблицу по полю DATETIME следующим образом:

SELECT * FROM `calendar` WHERE startTime = '2010-04-29'"

... и я хотел бы получить строку со значением DATETIME "2010-04-29 10:00".

Какие-либо предложения? Спасибо.

Мэнни Калавера
источник

Ответы:

163

Используйте следующее:

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'

Для справки у меня есть таблица с 2 миллионами записей, я выполнил аналогичный запрос. Ответ Салилса занял 4,48 секунды, приведенный выше - 2,25 секунды.

Так что, если таблица БОЛЬШАЯ, я бы скорее предложил это.

Дэвид
источник
8
Первый ответ настолько медленный, потому что он должен форматировать каждое datetime в строку перед сравнением. Ваш лучше, потому что он напрямую сравнивает только часть даты из поля, но по-прежнему не может использовать индекс (проверено на mysql 5.1)
Marki555
1
Если производительность является проблемой, возможно, стоит подумать о том, чтобы сохранить часть даты и времени отдельно, чтобы на части даты можно было разместить ИНДЕКС.
Thijs Riezebeek
1
Этот запрос не сможет использовать индекс, если startTimeон проиндексирован.
Замрони П.
43

Если вы хотите выбрать все строки, в которых часть DATE столбца DATETIME соответствует определенному литералу, вы не можете сделать это так:

WHERE startTime = '2010-04-29'

потому что MySQL не может напрямую сравнивать DATE и DATETIME. Что делает MySQL, он расширяет заданный литерал DATE временем '00: 00: 00 '. Итак, ваше состояние становится

WHERE startTime = '2010-04-29 00:00:00'

Уж точно не то, что вы хотите!

Условие - это диапазон, поэтому его следует задавать как диапазон. Есть несколько возможностей:

WHERE startTime BETWEEN '2010-04-29 00:00:00' AND '2010-04-29 23:59:59'
WHERE startTime >= '2010-04-29' AND startTime < ('2010-04-29' + INTERVAL 1 DAY)

Существует крошечная вероятность того, что первый ошибается - когда ваш столбец DATETIME использует субсекундное разрешение и назначена встреча в 23:59:59 + эпсилон. В общем, предлагаю использовать второй вариант.

Оба варианта могут использовать индекс startTime, который станет важным при росте таблицы.

XL_
источник
9
Версия Дэвида не очень хороша, в ней нельзя использовать индексы. Для того, чтобы использовать индекс, вы должны фильтр на колонке непосредственно, а не на результат функции ( date(), year(), datediff()или любой аналогичный)
Marki555
Я искал, как mysql преобразует дату в datetime, спасибо за очистку, которую он добавляет 00:00:00. теперь мои результаты имеют смысл
Бухгалтер م
1
Это правильное быстрое решение по сравнению с другими ответами, которые не могут использовать индекс, если он доступен
Замрони П.
23
SELECT * FROM `calendar` WHERE DATE_FORMAT(startTime, "%Y-%m-%d") = '2010-04-29'"

ИЛИ

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'
Салил
источник
25
Это ужасный вопрос. Избегайте этого любой ценой. Если в startTime есть индекс, его нельзя использовать в этом запросе, поскольку он применяет функцию к столбцу, а не использует ее напрямую. Это означает, что любой подобный запрос потребует полного сканирования таблицы. Для большой таблицы это будет означать чрезвычайно медленный запрос.
steveayre
Я согласен, его ответ неверен - правильный ответ Дэвид опубликовал ниже.
mindplay.dk
1
Пожалуйста, используйте ответ Дэвида, потому что он намного быстрее. Этот действительный, но не очень хороший для скорости ...
xarlymg89
1
@ CarlosAlbertoMartínezGadea Эта версия работает медленно, потому что ей необходимо преобразовать каждое значение в строку перед сравнением ... Версия Дэвида не нуждается в этом, но по-прежнему не может использовать индексы, поэтому не является оптимальной. См. Ответ XL_ для версии, которая может использовать index. К сожалению, в mysql нет лучшего способа сделать это должным образом
Marki555
1
Я отклонил этот ответ, потому что запрос не может использовать индекс, а ответ @ XL_ -.
pedromanoel
2
SELECT * FROM sample_table WHERE last_visit = DATE_FORMAT('2014-11-24 10:48:09','%Y-%m-%d %H:%i:%s')

это для формата datetime в mysql с использованием DATE_FORMAT(date,format).

RT
источник
1
SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29';

это помогает, вы можете преобразовать значения, как DATEперед сравнением.

Сарат
источник
0

Вы можете преобразовать поле DATETIME в DATE как:

SELECT * FROM `calendar` WHERE CAST(startTime AS DATE) = '2010-04-29'

Это очень эффективно.

SGAmpere
источник
1
Нет, это тоже неэффективно. это не сможет использовать индекс, если startTimeон проиндексирован
Замрони П.
-6
SELECT * FROM `calendar` WHERE startTime like '2010-04-29%'

Вы также можете использовать операторы сравнения с датами MySQL, если хотите найти что-то после или до. Это потому, что они написаны таким образом (от наибольшего значения к наименьшему с ведущими нулями), что простая сортировка строк будет правильно их сортировать.

Флетчер Мур
источник