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.