Tarih / saat sütunundan tarih nasıl seçilir?


238

2009-10-20 10:00:00 gibi değerlere sahip "datetime" türünde bir sütun var

Tarih saatinden ayıklamak ve gibi bir sorgu yazmak istiyorum:

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

Aşağıdakiler bunu yapmanın en iyi yolu mu?

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

Ancak bu boş bir sonuç kümesi döndürür. Baska öneri?

Yanıtlar:


456

MySQL'in DATE()fonksiyonunu kullanabilirsiniz :

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

Bunu da deneyebilirsiniz:

WHERE datetime LIKE '2009-10-20%'

Kullanımın performans üzerindeki etkileri hakkında bilgi için bu cevaba bakınız LIKE.


2
bunu denedim: Nerede DATE (datetime) = '2009-10-20', işe yarıyor
mysqllearner

44
Birincisi çok yavaş ve dizinleri yok sayar. 'Tarih%' GİBİ olması daha iyidir
kachar

NEREDE TARİH (datetime) '% anahtar kelime%' GİBİ çalışıyor, teşekkürler
silvia zulinka

2
Rails zaman dilimi UTC dışında bir şey ise, bu beklendiği gibi çalışmaz inanıyorum. Bunun nedeni, DATE () öğesinin UTC değerini UTC'ye çözmesidir. Yani "Cum, 30 Aralık 2016 00:00:00 SGT +08: 00" gibi bir tarih "2016-12-30" için sorgulayıp sorgulamadığımızı bulmayı umuyoruz. Neden? Çünkü DATE (), karşılaştırma yapmadan önce bunu "2016-12-29 16:00:00 UTC" olarak UTC eşdeğerine çözecektir. Yanılıyorsam beni düzeltin çünkü bu da yakın zamana kadar benim için bir sorun oldu.
Tikiboy

NEREDE TARİH (datetime) = '{? Sdate} bir Crystal Reports parametresi için mükemmel çalışıyor! İyi iş!
MikeMighty

94

Kullanmanın WHERE DATE(datetime) = '2009-10-20' performans sorunları var . Belirtildiği gibi burada :

  • DATE()eşleşmeyenler de dahil olmak üzere tüm satırlar için hesaplanır .
  • sorgu için bir dizin kullanılmasını imkansız hale getirecektir.

Kullanın BETWEENveya >, <, =bir dizin kullanmasına izin operatörleri:

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

Güncelleme: Etki kullanımıyla ilgili LIKEbir dizinli sütunda yerine operatörlerin yüksektir . Bunlar 1.176.000 satır içeren bir tabloda bazı test sonuçlarıdır:

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

Aynı sorgu üzerinden ikinci bir çağrı yaparken fark daha da yüksektir: 2984ms vs 7ms (evet, sadece 7 milisaniye!). Hibernate kullanarak bir projede bazı eski kodu yeniden yazarken buldum.


MySQL uygulama otomatik olarak dönüştürür eğer İlginç, DATE(datetime)hiç BETWEEN AND sahneleri behine biz kısa açıklama almak ve performansı serin. Neden olmasın? Neden bunu yapmadılar? :)
Kiraz

Çünkü böyle bir şey DATE(datetime) in (:list)işe yaramıyorBETWEEN
Tim

25

Tarih saatini YMD bölümüne biçimlendirebilirsiniz:

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

2
Ve bu şekilde gerekirse sadece zaman bölümünü alabilirsiniz:DATE_FORMAT(datetime, '%H:%i:%S')
Metafaniel

bu datetime'ı biçimlendirmek için harika çalışır ancak bunun karşılığında veritabanı adı DATE_FORMAT (columnName, '% Y-% m-% d') dizisinin sonunda istenen ad olarak ayarlamak için yeni bir dizi döndürür. Belgeler dev.mysql.com/doc/refman/8.0/en/…
Ridha Rezzag

15

Sayfadaki tüm yanıtların istenen sonucu döndürmesine rağmen, hepsinde performans sorunları var. Asla WHEREyan tümcedeki alanlarda ( DATE()hesaplama dahil ) hesaplamalar yapmayın, çünkü bu hesaplama tablodaki tüm satırlarda yapılmalıdır.

BETWEEN ... ANDYapı kendisi diğer sorunları (Ben soru sorulduğunda MySQL 2009 yılında destek vermedi inanıyoruz mikrosaniye işlemleri,) vardır bitiş tarihinde 23:59:59 sözdizimi belirtmek için bir gerektiren her iki sınır koşulları için dahildir.

Bir MySQL timestampalanını belirli bir gün için sorgulamanın doğru yolu , istenen tarihe karşılık Eşit Fazladan Büyük ve sonraki saat için herhangi bir saat belirtilmeksizin Küçüktür değerini kontrol etmektir.

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

Bu, en hızlı performans gösteren, en düşük bellek, en az kaynak yoğun yöntemdir ve ek olarak tüm MySQL özelliklerini ve ikinci-altı zaman damgası hassasiyeti gibi köşe durumlarını destekler. Ayrıca, geleceğin kanıtı.


1
Ve performans argümanınızı kullanarak, tablonun her satırında "> =" ve "<" eşit olarak hesaplanıyor mu yoksa SQL sunucusu bir sayının diğerinden daha büyük olup olmadığını sadece "sihirli bir şekilde" biliyor mu? :-)
Javier Guerrero

@JavierGuerrero: Örneğim iki sabitleri karşılaştırıyor: Biri tablodan ve dize değişmezinden.
dotancohen

"Tablodan bir" sabit değildir, her satır için değişir, bu nedenle her satır için aynı hesaplama yapılmalıdır (ve her ikisinin de karşılaştırmayı gerçekleştirmek için zamana dönüştürülmesi gerekir)
Javier Guerrero

9

İşte tüm biçimler

Bunun datetimedeğer, tabloyu içeren sütun olduğunu varsayalım 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

Kullanabilirsiniz:

DATEDIFF ( day , startdate , enddate ) = 0

Veya:

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

Veya:

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

5

tarih işlevini kullanmanın basit ve en iyi yolu

misal

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

VEYA

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

-5

Peki, LIKEifadede kullanmak WHERE datetime LIKE '2009-10-20%' bu durumda çalışması gereken en iyi seçenektir

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.