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 мільйони, я провів подібний запит. Відповідь Salils зайняла 4,48 секунди, вищезазначена - 2,25 секунди.

Отже, якщо таблиця ВЕЛИКА, я б скоріше запропонував це.


8
Перша відповідь є настільки повільною, тому що перед порівнянням вона повинна форматувати кожну дату та час у рядок. Ваш краще, оскільки він безпосередньо порівнює лише частину дати з поля, але все одно не може використовувати індекс (перевірено на mysql 5.1)
Marki555,

1
Якщо продуктивність є проблемою, можливо, варто розглянути можливість збереження частини дати та часу окремо, щоб ІНДЕКС міг бути розміщений у частині дати.
Тійс Різебек,

1
Цей запит не зможе використовувати індекс, якщо startTimeіндексується.
Замроні П. Джухара

43

Якщо ви хочете вибрати всі рядки, де частина DATE стовпця DATETIME відповідає певному літералу, ви не можете зробити це так:

WHERE startTime = '2010-04-29'

оскільки MySQL не може безпосередньо порівняти ДАТУ і ДАТУ. Те, що робить 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 + epsilon. Загалом я пропоную використовувати другий варіант.

Обидва варіанти можуть використовувати індекс на startTime, що стане важливим, коли таблиця зростатиме.


9
Версія Девіда погана, вона не може використовувати індекси. Для того, щоб використовувати індекс, ви повинні фільтр на колонці безпосередньо, а нема на результат функції ( date(), year(), datediff()або будь-який аналогічний)
Marki555

Я шукав, як mysql перетворює дату на дату і час, дякую за очищення доданого 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'

24
Це жахливий запит. Уникайте цього будь-якою ціною. Якщо в startTime є індекс, він не може бути використаний цим запитом, оскільки він застосовує функцію до стовпця, а не використовує її безпосередньо. Це означає, що будь-який такий запит вимагатиме повного сканування таблиці. Для великої таблиці це буде означати надзвичайно повільний запит.
steveayre

Я згоден, його відповідь неправильна - правильну відповідь Давид розмістив нижче.
mindplay.dk

1
Будь ласка, використовуйте відповідь від Девіда, бо це набагато швидше. Цей дійсний, але
поганий

1
@ CarlosAlbertoMartínezGadea Ця версія є повільною, оскільки перед порівнянням вона повинна відформатувати кожне значення в рядку ... Версія Девіда не потребує цього, але все ще не може використовувати індекси, тому не є оптимальною. Дивіться відповідь від XL_ щодо версії, яка може використовувати індекс. На жаль, немає кращого способу зробити це правильно в 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).


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'

Це дуже ефективно.


1
Ні, це теж не ефективно. це не зможе використовувати індекс, якщо startTimeіндексується
Замроні П. Джухара

-6
SELECT * FROM `calendar` WHERE startTime like '2010-04-29%'

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.