Як вибрати дату з стовпця "Дата"?


238

У мене стовпець типу "datetime" зі значеннями, як 2009-10-20 10:00:00

Я хочу витягнути дату з дати і написати запит на зразок:

SELECT * FROM 
data 
WHERE datetime = '2009-10-20' 
ORDER BY datetime DESC

Чи є наступний найкращий спосіб зробити це?

SELECT * FROM 
data 
WHERE datetime BETWEEN('2009-10-20 00:00:00' AND '2009-10-20 23:59:59')
ORDER BY datetime DESC

Однак це повертає порожній набір результатів. Будь-які пропозиції?

Відповіді:


456

Ви можете використовувати DATE()функцію MySQL :

WHERE DATE(datetime) = '2009-10-20'

Ви також можете спробувати це:

WHERE datetime LIKE '2009-10-20%'

Дивіться цю відповідь, щоб отримати інформацію про наслідки використання продуктивності LIKE.


2
спробував це: Де DATE (datetime) = '2009-10-20', він працює
mysqllearner

44
Перший дуже повільний і ігнорує індекси. Краще мати LIKE 'date%'
качар

ДЕ ДАТА (дата) ПОДОБАЙТЕ "% ключове слово%" працює, дякую
silvia zulinka

2
Я вважаю, що це працює не так, як очікувалося, якщо часовий пояс Rails - це щось інше, ніж UTC. Це тому, що DATE () визначає значення стовпця на UTC. Тож дата, як-от "Пт, 30 грудня 2016 00:00:00 SGT +08: 00", яку ми очікуємо знайти, якщо ми отримали запит на "2016-12-30", не буде знайдено. Чому? Тому що DATE () вирішить його до свого еквівалента UTC, перш ніж робити порівняння, яке є "2016-12-29 16:00:00 UTC". Виправте мене, якщо я помиляюся, оскільки це ще недавно було для мене.
Тікібой

WHERE DATE (datetime) = '{? Sdate} прекрасно працює для параметра Crystal Reports! Хороша робота!
MikeMighty

94

Використання WHERE DATE(datetime) = '2009-10-20' має проблеми з продуктивністю . Як зазначено тут :

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

Використовуйте BETWEENабо >, <, =оператори , які дозволяють використовувати індекс:

SELECT * FROM data 
WHERE datetime BETWEEN '2009-10-20 00:00:00' AND '2009-10-20 23:59:59'

Оновлення: вплив на використання LIKEзамість операторів в індексованих стовпці є високим . Ось деякі результати тестів на таблиці з 1,176 000 рядків:

  • використовуючи datetime LIKE '2009-10-20%'=> 2931мс
  • використовуючи datetime >= '2009-10-20 00:00:00' AND datetime <= '2009-10-20 23:59:59'=> 168 мс

Здійснюючи другий дзвінок над тим же запитом, різниця ще більша: 2984 мс проти 7 мс (так, всього 7 мілісекунд!). Я виявив це, переписуючи старий код у проекті за допомогою Hibernate.


Цікаво, що якщо реалізація MySql автоматично перетворюється DATE(datetime)на BETWEEN AND сцени, ми отримуємо коротку заяву та круті показники. Чому ні? Чому вони цього не зробили? :)
Вишня

Тому що щось на кшталт DATE(datetime) in (:list)не працюєBETWEEN
Тім

25

Ви можете відформатувати дату в частині YMD:

DATE_FORMAT(datetime, '%Y-%m-%d')

2
І таким чином ви можете отримати лише частину часу, якщо потрібно:DATE_FORMAT(datetime, '%H:%i:%S')
Metafaniel

це чудово формує час дати, але взамін, база даних поверне новий масив, щоб встановити ім'я для цього просто оголосити потрібне ім’я в кінці DATE_FORMAT (стовпець ім'я, '% Y-% m-% d') arrayName для більш детальної перевірки документації dev.mysql.com/doc/refman/8.0/en/…
Ridha Rezzag

15

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

BETWEEN ... ANDКонструкт включно для обох граничних умов, що вимагає один , щоб вказати 23:59:59 синтаксису на дату закінчення , який сам має інші проблеми (мікросекунди угоду, які я вважаю , MySQL не підтримує в 2009 році , коли було поставлено питання).

Правильний спосіб запиту timestampполя MySQL для конкретного дня - це перевірити наявність Greater Than-Equals на бажану дату, а на менший - ніж на наступний день, без вказаної години.

WHERE datetime>='2009-10-20' AND datetime<'2009-10-21'

Це найшвидший метод, що має найменший обсяг пам’яті, найменш ресурсомісткий метод, а також підтримує всі функції MySQL та кутові випадки, такі як точність часової позначки під секунду. Крім того, це майбутній доказ.


1
І, використовуючи свій аргумент продуктивності, чи "> =" і "<" однаково обчислюються в кожному рядку таблиці, або SQL-сервер просто "магічно" знає, чи число більше, ніж інші? :-)
Хав'єр Герреро

@JavierGuerrero: У моєму прикладі порівнюються дві константи: одна із таблиці та літеральна рядок.
dotancohen

"Один із таблиці" не є константою, він змінюється для кожного ряду, тому для кожного ряду потрібно робити однаковий розрахунок (а також обидва повинні бути перетворені на епоху, щоб виконати порівняння)
Хав'єр Герреро

9

Тут усі формати

Скажіть, це стовпець, який містить datetimeзначення, таблицю data.

+--------------------+
| date_created       |
+--------------------+
| 2018-06-02 15:50:30|
+--------------------+

mysql> select DATE(date_created) from data;
+--------------------+
| DATE(date_created) |
+--------------------+
| 2018-06-02         |
+--------------------+

mysql> select YEAR(date_created) from data;
+--------------------+
| YEAR(date_created) |
+--------------------+
|               2018 |
+--------------------+

mysql> select MONTH(date_created) from data;
+---------------------+
| MONTH(date_created) |
+---------------------+
|                   6 |
+---------------------+

mysql> select DAY(date_created) from data;
+-------------------+
| DAY(date_created) |
+-------------------+
|                 2 |
+-------------------+

mysql> select HOUR(date_created) from data;
+--------------------+
| HOUR(date_created) |
+--------------------+
|                 15 |
+--------------------+

mysql> select MINUTE(date_created) from data;
+----------------------+
| MINUTE(date_created) |
+----------------------+
|                   50 |
+----------------------+

mysql> select SECOND(date_created) from data;
+----------------------+
| SECOND(date_created) |
+----------------------+
|                   31 |
+----------------------+

5

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

DATEDIFF ( day , startdate , enddate ) = 0

Або:

DATEPART( day, startdate ) = DATEPART(day, enddate)
AND 
DATEPART( month, startdate ) = DATEPART(month, enddate)
AND
DATEPART( year, startdate ) = DATEPART(year, enddate)

Або:

CONVERT(DATETIME,CONVERT(VARCHAR(12), startdate, 105)) = CONVERT(DATETIME,CONVERT(VARCHAR(12), enddate, 105))

5

простий і найкращий спосіб використовувати функцію дати

приклад

SELECT * FROM 
data 
WHERE date(datetime) = '2009-10-20' 

АБО

SELECT * FROM 
data 
WHERE date(datetime ) >=   '2009-10-20'  && date(datetime )  <= '2009-10-20'

-5

Що ж, використання LIKEв операторі є найкращим варіантом, який WHERE datetime LIKE '2009-10-20%' він повинен працювати в цьому випадку

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