MySQL ВИБІРТЕ, де дата відповідає дням (і не обов'язково часу)


127

У мене є таблиця, що містить стовпчик дати. Я хочу повернути всі записи за певний день незалежно від часу. Або іншими словами, якби у моїй таблиці були лише 4 наступні записи, тоді, якщо я обмежуся на 2012-12-25, буде повернуто лише 2-й та 3-й записи.

2012-12-24 00:00:00
2012-12-25 00:00:00
2012-12-25 06:00:00
2012-12-26 05:00:00

Див відповідь Джона Ву в stackoverflow.com/questions/14769026 / ...
ekerner

Відповіді:


326

НІКОЛИ не використовуйте селектор на кшталт DATE(datecolumns) = '2012-12-24'- це вбивця продуктивності:

  • він буде розрахований DATE()для всіх рядків, включаючи ті, які не відповідають
  • це унеможливить використання індексу для запиту

Це набагато швидше у використанні

SELECT * FROM tablename 
WHERE columname BETWEEN '2012-12-25 00:00:00' AND '2012-12-25 23:59:59'

оскільки це дозволить використовувати індекс без розрахунку.

EDIT

Як зазначає Used_By_Already, за час, починаючи з первинної відповіді в 2012 році, з'явилися версії MySQL, де використання "23: 59: 59" як закінчення дня вже не є безпечним. Оновлена ​​версія повинна читати

SELECT * FROM tablename 
WHERE columname >='2012-12-25 00:00:00'
AND columname <'2012-12-26 00:00:00'

Суть відповіді, тобто уникнення селектора на обчисленому виразі, звичайно, все ще існує.


Я збирався прокоментувати, що рішення a1ex07 здається не таким хорошим, як інші. Прочитавши твій пост, можливо, мені потрібно змінити своє мислення!
користувач1032531

2
Щойно перевірене на двох серверах, вищезгадане МНОГО (на 10 разів принаймні) швидше, ніж дата () = '', особливо для величезних таблиць. Спасибі
zzapper

1
@KonradViltersten Я використав дуже багатослівний спосіб, щоб сформулювати запит, щоб зробити його більш читабельним і загнати додому мою думку, аби уточнити його. Відповідь a1ex07 має синтаксис розрідженого типу.
Євген Рік

9
@KonradViltersten - ще краще: WHERE col >= '2012-12-25' AND col < '2012-12-25' + INTERVAL 1 DAY. Це дозволяє уникнути 0 раз і працює DATE, DATETIME, DATETIME(6)і т.д. І справа з високосного дня і т.д.
Рік Джеймс

1
'2012-12-25 23:59:59' НЕ ВІДМОВА як кінець дня, це завжди була поганою ідеєю, і це призведе до помилок у версіях MySQL, які підтримують точність у другу секунду. Набагато краще використовувати підхід Ріка Джеймса (вище) або a1ex07 (інша відповідь)
Used_By_Already

34

... WHERE date_column >='2012-12-25' AND date_column <'2012-12-26'може потенційно працювати краще (якщо у вас є індекс на date_column), ніж DATE.


1
Мені справді цікаво, що швидше - це чи BETWEENрішення ... хтось зачарував?
jave.web

6
Це не повинно бути різниці. BETWEENце лише спосіб писати field >= value1 and fied<= value2.
a1ex07

1
Зауважте, що в посібнику MySQL: "Для найкращих результатів при використанні BETWEEN зі значеннями дати або часу використовуйте CAST () для явного перетворення значень у потрібний тип даних. Приклади: Якщо ви порівнюєте DATETIME з двома значеннями DATE, конвертуйте DATE значення DATETIME. Якщо ви використовуєте констант рядка, такий як '2001-1-1' порівняно з DATE, наведіть рядок на DATE. " Тому, якщо вони не є одним і тим же типом, найкраще їх чітко викласти.
techdude

21

Ви можете використовувати %:

SELECT * FROM datetable WHERE datecol LIKE '2012-12-25%'

13
LIKE здається настільки ж повільним, як і DATE (datetimecol). Краще використовувати рішення Eugen або a1ex07.
Марі Фішер

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