MySQL membandingkan string DATE dengan string dari bidang DATETIME

93

Saya punya pertanyaan: Apakah mungkin untuk memilih dari database MySQL dengan membandingkan satu string DATE "2010-04-29" dengan string yang disimpan sebagai DATETIME (2010-04-29 10:00)?

Saya memiliki satu pemilih tanggal yang memfilter data dan saya ingin menanyakan tabel berdasarkan bidang DATETIME seperti ini:

SELECT * FROM `calendar` WHERE startTime = '2010-04-29'"

... dan saya ingin mendapatkan baris yang memiliki nilai DATETIME "2010-04-29 10:00".

Ada saran? Terima kasih.

Manny Calavera
sumber

Jawaban:

163

Gunakan yang berikut ini:

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'

Hanya untuk referensi, saya memiliki tabel catatan 2 juta, saya menjalankan kueri serupa. Jawaban Salils butuh waktu 4,48 detik, di atas butuh 2,25 detik.

Jadi jika mejanya BESAR saya sarankan ini.

David
sumber
8
Jawaban pertama sangat lambat, karena harus memformat setiap tanggal waktu menjadi string sebelum dibandingkan. Anda lebih baik, karena langsung membandingkan hanya bagian tanggal dari lapangan, tetapi masih tidak dapat menggunakan indeks (diuji pada mysql 5.1)
Marki555
1
Jika kinerja menjadi masalah, mungkin ada baiknya mempertimbangkan untuk menyimpan bagian tanggal dan waktu secara terpisah, sehingga INDEX dapat ditempatkan pada bagian tanggal.
Thijs Riezebeek
1
Kueri ini tidak akan dapat menggunakan indeks jika startTimediindeks.
Zamrony P. Juhara
43

Jika Anda ingin memilih semua baris di mana bagian DATE dari kolom DATETIME cocok dengan literal tertentu, Anda tidak dapat melakukannya seperti ini:

WHERE startTime = '2010-04-29'

karena MySQL tidak dapat membandingkan DATE dan DATETIME secara langsung. Apa yang dilakukan MySQL, itu memperpanjang literal DATE yang diberikan dengan waktu '00: 00: 00 '. Jadi kondisimu menjadi

WHERE startTime = '2010-04-29 00:00:00'

Tentu bukan yang Anda inginkan!

Kondisinya adalah kisaran dan karenanya harus diberikan sebagai kisaran. Ada beberapa kemungkinan:

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)

Ada kemungkinan kecil untuk kesalahan pertama - ketika kolom DATETIME Anda menggunakan resolusi sub-detik dan ada janji temu pada pukul 23:59:59 + epsilon. Secara umum saya menyarankan untuk menggunakan varian kedua.

Kedua varian dapat menggunakan indeks pada startTime yang akan menjadi penting saat tabel berkembang.

XL_
sumber
9
Versi David tidak bagus, tidak bisa menggunakan indeks. Untuk menggunakan indeks, Anda harus filter pada kolom secara langsung, bukan pada hasil dari fungsi ( date(), year(), datediff()atau serupa)
Marki555
Saya sedang mencari bagaimana mysql mengubah tanggal menjadi datetime, terima kasih telah membersihkannya 00:00:00. sekarang hasil saya masuk akal
Akuntan م
1
Ini adalah solusi cepat yang tepat dibandingkan dengan jawaban lain yang tidak dapat menggunakan indeks jika tersedia
Zamrony P. Juhara
23
SELECT * FROM `calendar` WHERE DATE_FORMAT(startTime, "%Y-%m-%d") = '2010-04-29'"

ATAU

SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29'
Salil
sumber
25
Ini pertanyaan yang buruk. Hindari ini dengan cara apa pun. Jika ada indeks pada startTime, itu tidak dapat digunakan oleh kueri ini, karena ini menerapkan fungsi ke kolom daripada menggunakannya secara langsung. Itu berarti setiap kueri seperti ini akan memerlukan pemindaian tabel lengkap. Pada tabel besar, ini berarti kueri sangat lambat.
steveayre
Saya setuju, jawabannya salah - jawaban yang benar diposting oleh David di bawah ini.
mindplay.dk
1
Tolong gunakan jawaban dari David, karena ini jauh lebih cepat. Yang ini valid, tapi tidak bagus untuk kecepatan ...
xarlymg89
1
@ CarlosAlbertoMartínezGadea Versi ini lambat karena harus memformat setiap nilai ke string sebelum dibandingkan ... Versi David tidak membutuhkannya, tetapi masih tidak dapat menggunakan indeks, jadi tidak optimal. Lihat jawaban dari XL_ untuk versi yang bisa menggunakan index. Sayangnya tidak ada cara yang lebih baik untuk melakukannya dengan benar di mysql
Marki555
1
Saya menurunkan suara jawaban ini karena kueri tidak dapat menggunakan indeks, sedangkan jawaban @ XL_ menggunakannya.
pedromanoel
2
SELECT * FROM sample_table WHERE last_visit = DATE_FORMAT('2014-11-24 10:48:09','%Y-%m-%d %H:%i:%s')

ini untuk format datetime di mysql menggunakan DATE_FORMAT(date,format).

RT
sumber
1
SELECT * FROM `calendar` WHERE DATE(startTime) = '2010-04-29';

ini membantu, Anda dapat mengonversi nilai seperti DATEsebelum membandingkan.

Sarath
sumber
0

Anda dapat mentransmisikan bidang DATETIME menjadi DATE sebagai:

SELECT * FROM `calendar` WHERE CAST(startTime AS DATE) = '2010-04-29'

Ini sangat efisien.

SGAmpere
sumber
1
Tidak, itu tidak efisien juga. ini tidak akan dapat menggunakan indeks jika startTimediindeks
Zamrony P. Juhara
-6
SELECT * FROM `calendar` WHERE startTime like '2010-04-29%'

Anda juga dapat menggunakan operator perbandingan pada tanggal MySQL jika Anda ingin menemukan sesuatu setelah atau sebelumnya. Ini karena mereka ditulis sedemikian rupa (nilai terbesar ke terkecil dengan nol di depan) sehingga pengurutan string sederhana akan mengurutkannya dengan benar.

Fletcher Moore
sumber