Bagaimana cara memilih tanggal dari kolom datetime?

238

Saya memiliki kolom tipe "datetime" dengan nilai-nilai seperti 2009-10-20 10:00:00

Saya ingin mengekstrak tanggal dari datetime dan menulis kueri seperti:

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

Apakah mengikuti cara terbaik untuk melakukannya?

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

Namun ini mengembalikan resultset kosong. Ada saran?

mysqllearner
sumber

Jawaban:

456

Anda dapat menggunakan DATE()fungsi MySQL :

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

Anda juga dapat mencoba ini:

WHERE datetime LIKE '2009-10-20%'

Lihat jawaban ini untuk info tentang implikasi kinerja penggunaan LIKE.

Priyank Bolia
sumber
2
mencoba yang satu ini: Di ​​mana DATE (datetime) = '2009-10-20', ia berfungsi
mysqllearner
44
Yang pertama sangat lambat dan mengabaikan indeks. Lebih baik memiliki LIKE 'date%'
kachar
WHERE DATE (datetime) SUKA '% kata kunci%' itu berfungsi, terima kasih
silvia zulinka
2
Saya percaya ini tidak berfungsi seperti yang diharapkan jika zona waktu Rails adalah sesuatu selain UTC. Ini karena DATE () menyelesaikan nilai kolom ke UTC. Jadi tanggal seperti "Jum, 30 Des 2016 00:00:00 SGT +08: 00" yang kami harapkan akan ditemukan jika kami menanyakan "2016-12-30" tidak akan ditemukan. Mengapa? Karena DATE () akan menyelesaikannya ke UTC yang setara sebelum melakukan perbandingan, yaitu "2016-12-29 16:00:00 UTC". Perbaiki saya jika saya salah karena ini juga menjadi masalah bagi saya sampai saat ini.
Tikiboy
WHERE DATE (datetime) = '{? Sdate} berfungsi dengan sempurna untuk parameter Crystal Reports! Kerja bagus!
MikeMighty
94

Penggunaan WHERE DATE(datetime) = '2009-10-20' memiliki masalah kinerja . Seperti yang dinyatakan di sini :

  • itu akan menghitung DATE()untuk semua baris, termasuk yang tidak cocok.
  • itu akan membuat tidak mungkin untuk menggunakan indeks untuk permintaan.

Gunakan BETWEENatau >, <, =operator yang memungkinkan untuk menggunakan indeks:

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

Update: yang berdampak pada menggunakan LIKEbukannya operator di kolom diindeks tinggi . Ini adalah beberapa hasil tes di atas meja dengan 1.176.000 baris:

  • menggunakan datetime LIKE '2009-10-20%'=> 2931 ms
  • menggunakan datetime >= '2009-10-20 00:00:00' AND datetime <= '2009-10-20 23:59:59'=> 168ms

Ketika melakukan panggilan kedua melalui permintaan yang sama, perbedaannya bahkan lebih tinggi: 2984 ms vs 7 ms (ya, hanya 7 milidetik!). Saya menemukan ini ketika menulis ulang beberapa kode lama pada suatu proyek menggunakan Hibernate.

IvanRF
sumber
Menarik, jika implementasi MySql dikonversi secara otomatis DATE(datetime)untuk BETWEEN AND menjalankan adegan, kami mendapatkan pernyataan pendek dan performa keren. Kenapa tidak? Kenapa mereka tidak melakukan ini? :)
Cherry
Karena sesuatu seperti DATE(datetime) in (:list)tidak bekerja denganBETWEEN
Tim
25

Anda dapat memformat datetime ke bagian YMD:

DATE_FORMAT(datetime, '%Y-%m-%d')
Prusprus
sumber
2
Dan dengan cara ini Anda hanya bisa mendapatkan bagian waktu jika diperlukan:DATE_FORMAT(datetime, '%H:%i:%S')
Metafaniel
ini berfungsi hebat memformat datetime tetapi sebagai imbalannya database akan mengembalikan array baru untuk menetapkan nama untuk itu hanya iklan nama yang diinginkan di akhir DATE_FORMAT (kolomName, '% Y-% m-% d') arrayName untuk lebih jelasnya periksa dokumentasi dev.mysql.com/doc/refman/8.0/en/…
Ridha Rezzag
15

Meskipun semua jawaban pada halaman akan mengembalikan hasil yang diinginkan, mereka semua memiliki masalah kinerja. Jangan pernah melakukan perhitungan pada bidang dalam WHEREklausa (termasuk DATE()perhitungan) karena perhitungan itu harus dilakukan pada semua baris dalam tabel.

The BETWEEN ... ANDmembangun inklusif untuk kedua kondisi perbatasan, membutuhkan satu untuk menentukan 23:59:59 sintaks pada tanggal akhir yang sendiri memiliki masalah lain (transaksi mikrodetik, yang saya percaya MySQL tidak mendukung pada 2009 ketika pertanyaan diajukan).

Cara yang tepat untuk menanyakan timestampbidang MySQL untuk hari tertentu adalah dengan memeriksa Greater-Than-Equals terhadap tanggal yang diinginkan, dan Less-Than untuk hari berikutnya, tanpa jam yang ditentukan.

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

Ini adalah yang berkinerja tercepat, memori terendah, metode intensif sumber daya terendah, dan juga mendukung semua fitur MySQL dan kasing-kasus seperti ketepatan cap waktu sub-detik. Selain itu, ini adalah bukti masa depan.

dotancohen
sumber
1
Dan, menggunakan argumen kinerja Anda, apakah "> =" dan "<" sama-sama dihitung pada setiap baris tabel, atau server SQL hanya "secara ajaib" yang tahu jika angka lebih besar dari yang lain? :-)
Javier Guerrero
@ JavierGuerrero: Contoh saya membandingkan dua konstanta: Satu dari tabel dan string literal.
dotancohen
"Satu dari tabel" bukan konstanta, itu bervariasi untuk setiap baris, sehingga perhitungan yang sama harus dilakukan untuk setiap baris (dan juga, keduanya harus dikonversi ke zaman untuk melakukan perbandingan)
Javier Guerrero
9

Ini semua format

Katakan ini adalah kolom yang berisi datetimenilai, tabel 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 |
+----------------------+
Siraj Alam
sumber
5

Kamu bisa memakai:

DATEDIFF ( day , startdate , enddate ) = 0

Atau:

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

Atau:

CONVERT(DATETIME,CONVERT(VARCHAR(12), startdate, 105)) = CONVERT(DATETIME,CONVERT(VARCHAR(12), enddate, 105))
Michel van Engelen
sumber
5

cara sederhana dan terbaik untuk menggunakan fungsi tanggal

contoh

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

ATAU

SELECT * FROM 
data 
WHERE date(datetime ) >=   '2009-10-20'  && date(datetime )  <= '2009-10-20'
Raja Rama Mohan Thavalam
sumber
-5

Nah, menggunakan LIKEdalam pernyataan adalah pilihan terbaik WHERE datetime LIKE '2009-10-20%' yang seharusnya berfungsi dalam kasus ini

imran
sumber