MySQL SELECT tarihsaatin günle eşleştiği yer (ve mutlaka saat değil)


127

Tarih saat sütunu içeren bir tablom var. Belirli bir günün tüm kayıtlarını, saatten bağımsız olarak iade etmek istiyorum. Ya da başka bir deyişle, tablom sadece aşağıdaki 4 kaydı içeriyorsa, 2012-12-25 ile sınırlandırırsam sadece 2. ve 3. döndürülür.

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

Yanıtlar:


326

ASLA ASLA şunun gibi bir seçici kullanmayın DATE(datecolumns) = '2012-12-24'- bu bir performans katilidir:

  • DATE()eşleşmeyenler dahil tüm satırlar için hesaplar
  • sorgu için bir dizin kullanmayı imkansız hale getirecek

Kullanması çok daha hızlı

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

çünkü bu, hesaplamadan indeks kullanımına izin verecektir.

DÜZENLE

Used_By_Also tarafından işaret edildiği gibi, 2012'deki ilk cevaptan bu yana, MySQL'in gün sonu olarak "23: 59: 59" kullanımının artık güvenli olmadığı sürümleri ortaya çıktı. Güncellenmiş bir sürüm şöyle olmalıdır

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

Cevabın özü, yani hesaplanmış bir ifadede bir seçiciden kaçınma, elbette hala geçerli.


A1ex07'nin çözümünün diğerleri kadar iyi görünmediğini söylemek üzereydim. Gönderinizi okuduktan sonra, belki de düşüncelerimi tersine çevirmem gerekiyor!
user1032531

2
Sadece iki sunucu üzerinde test edildiğinde, özellikle büyük tablolar için, yukarısı çok (en az 10 kat) date () = '' den daha hızlıdır. Teşekkürler
zzapper

1
@KonradViltersten Sorguyu daha okunaklı hale getirmek ve amacıma ulaşmak için çok ayrıntılı bir yol kullandım, onu iyileştirmek yerine. A1ex07'nin cevabı seyrek sözdizimine sahiptir.
Eugen Rieck

9
: Daha iyisi - @KonradViltersten WHERE col >= '2012-12-25' AND col < '2012-12-25' + INTERVAL 1 DAY. Bu 0 defa önler ve çalışır DATE, DATETIME, DATETIME(6)vb Ve vb sıçrama gün, ile fırsatlar
Rick James

1
'2012-12-25 23:59:59' bir gün sonu olarak GEÇERLİ DEĞİLDİR, her zaman kötü bir fikirdi ve MySQL'in saniyenin altındaki zaman hassasiyetini destekleyen sürümlerinde hatalara neden olacaktır. Rick James'in (yukarıda) veya a1ex07'nin (diğer cevap) yaklaşımını kullanmak çok daha iyi
Used_By_Already

34

... WHERE date_column >='2012-12-25' AND date_column <'2012-12-26'potansiyel olarak daha iyi çalışabilir (date_column'da bir dizininiz varsa) DATE.


1
Aslında neyin daha hızlı olduğunu merak ediyorum - bu veya BETWEENçözüm ... kimse işaretlenmiş mi?
jave.web

6
Herhangi bir fark olmamalı. BETWEENsadece yazma yolu field >= value1 and fied<= value2.
a1ex07

1
MySQL Kılavuzu uyarınca: "BETWEEN'i tarih veya saat değerleriyle kullanırken en iyi sonuçları elde etmek için, değerleri açıkça istenen veri türüne dönüştürmek için CAST () kullanın. Örnekler: Bir DATETIME ile iki DATE değerini karşılaştırırsanız, TARİH'i dönüştürün değerleri DATETIME değerlerine çevirin. DATE ile karşılaştırmada '2001-1-1' gibi bir dize sabiti kullanırsanız, dizeyi DATE'e çevirin. " Dolayısıyla, hepsi aynı türde olmadıkça, en iyisi onları açıkça yayınlamaktır.
techdude

21

Şunları kullanabilirsiniz %:

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

13
LIKE, DATE (datetimecol) kadar yavaş görünüyor. En iyisi Eugen'in veya a1ex07'nin çözümünü kullanın.
Marie Fischer

3
Konu her zaman hız değildir. Bu yüzden bu çözümü beğendim. Çok daha okunabilir.
Simon Hansen

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.