Postgresql datetime alanlarındaki tarihleri ​​nasıl karşılaştırabilirim?


188

Postgresql (Windows sürüm 9.2.4) tarihleri ​​arasında karşılaştırırken garip bir senaryo ile karşı karşıya. Benim tablonun bir update_date 'saat dilimi olmadan zaman damgası' türü ile söylemek bir sütun var. Müşteri bu alanda yalnızca tarih (ör: 2013-05-03) veya saat içeren tarih (ör: 2013-05-03 12:20:00) ile arama yapabilir. Bu sütun şu anda tüm satırlar için zaman damgası değerine sahiptir ve aynı tarih bölümüne (2013-05-03) ancak zaman dilimindeki farka sahiptir.

Bu sütunu karşılaştırdığımda farklı sonuçlar alıyorum. Aşağıdaki gibi:

select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-03' -> No results

select * from table where update_date >= '2013-05-03' AND update_date < '2013-05-03' -> No results

select * from table where update_date >= '2013-05-03' AND update_date <= '2013-05-04' -> results found

select * from table where update_date >= '2013-05-03' -> results found

Benim sorum nasıl sonuç almak için ilk sorguyu nasıl yapabilirim, yani 3. sorgusu neden çalışıyor ama ilki değil?

Biri bana bu konuda yardımcı olabilir mi? Şimdiden teşekkürler.

Yanıtlar:


279

@Nicolai, yayınlama ve herhangi bir veri için durumun neden yanlış olduğu konusunda doğrudur. giriş dizesinde tarih manipülasyonu önlemek istediğiniz için ilk formu tercih sanırım, değil mi? korkmana gerek yok:

SELECT *
FROM table
WHERE update_date >= '2013-05-03'::date
AND update_date < ('2013-05-03'::date + '1 day'::interval);

Bu sözdizimi ( '2013-05-03'::dateve '1 day'::interval) PostgreSQL'e özgü mü?
Donmuş Alev

5
@FrozenFlame evet öyle. standart sözdizimi CAST('2013-05-03' AS DATE) + CAST('1 day' AS INTERVAL)(IIRC) olacaktır. YMMV DATEve INTERVAL.
sadece birileri

@FrozenFlame doğru, cevap dizeleri tarih türlerine dökmeden çalışmaz. Bir oyuncu kadrosu hala eksik. Bir alınması gerekir ::DATEnerede maddesinin birinci kısmına eklenen
StillLearningToCode

İyi WHERE update_date::date = '2013-05-03' çalışmaz ve belki biraz daha okunabilir mi?
MikeF

@MikeF OP bahsedilen update_dateoldu timestamp without timezone. o sütun üzerinde bir dizin varsaydım. yükleminiz bu dizini kullanmaz.
Birinin

46

Eğer karşılaştırdığımızda update_date >= '2013-05-03'aynı türe postgres silendirler değerleri değerleri karşılaştırmak için. Böylece '2013-05-03', '2013-05-03 00:00:00' olarak yayınlandı.

Güncelleme_tarihi = '2013-05-03 14:45:00' için ifadeniz şöyle olacaktır:

'2013-05-03 14:45:00' >= '2013-05-03 00:00:00' AND '2013-05-03 14:45:00' <= '2013-05-03 00:00:00'

Bu her zaman false

Bu sorunu çözmek için update_date öğesini şuraya yayınlayın date:

select * from table where update_date::date >= '2013-05-03' AND update_date::date <= '2013-05-03' -> Will return result

1
update_datesorgu parametresinin tek bir değerinin yayınlanması ve tablodaki her değerin yayınlanması son derece verimli değildir ve sunucunun bu sütundaki dizinlerden yararlanamayacağından emin olur. Ben -1 bu cazip.
sadece birileri

3
Evet, her bir değerin yayınlanmasının verimsiz olduğunu kabul ediyorum ve bu çözüm için -1 verebilirsiniz. Ama sorunun nedenini anlattım ve sorunu gösteren bir örnek verdim. Şimdi user2866264, sorgusunun neden beklenen satırları döndürmediğini ve benzersiz durumu için tam olarak hangi çözümün daha iyi olduğuna karar vereceğini biliyor.
Nicolai

@Nicolai: Cevabınız için çok teşekkürler. Cevabınızı takip ederek çalışır. Ayrıca açıklama için teşekkürler.
user2866264

1
@Nicolai - Postgres'in tarih değişmezini gece yarısının inişine genişletmesi hakkında söyledikleriniz göz önüne alındığında, hedef tek bir tarihte (3 Mayıs) işaretlenmiş kayıtları bulmaksa, bu kod doğru ve daha verimli olur: SELECT * FROM my_table WHERE update_date >= '2013-05-03' AND update_date < '2013-05-04'; (4 Mayıs kullanımını unutmayın yerine 3. ve eşit veya daha az yerine daha az bir işaret ile.)
Basil Bourque


2

Tarihle karşılaştırmak için Tarih dönüştürmeyi kullanın: Bunu Deneyin:

select * from table 
where TO_DATE(to_char(timespanColumn,'YYYY-MM-DD'),'YYYY-MM-DD') = to_timestamp('2018-03-26', 'YYYY-MM-DD')
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.