Bir dizi tarih oluşturmak için bu en uygun yoldur:
SELECT t.day::date
FROM generate_series(timestamp '2004-03-07'
, timestamp '2004-08-16'
, interval '1 day') AS t(day);
Ek date_trunc()gerekli değildir. İçin dökme date( day::date) örtülü olarak bunu yapmaz.
Ancak tarih değişmezlerini dategirdi parametresi olarak dönüştürmenin de bir anlamı yoktur . Au contraire, timestampen iyi seçimdir . Performanstaki avantaj küçüktür, ancak onu almamak için hiçbir neden yoktur. Ve DST (gün ışığından yararlanma saati) kurallarını, datearasında timestamp with time zoneve geri dönüştürmeyle birlikte gereksiz yere dahil etmezsiniz . Aşağıya bakınız.
Eşdeğer, daha az açık kısa sözdizimi:
SELECT day::date
FROM generate_series(timestamp '2004-03-07', '2004-08-16', '1 day') day;
Veya SELECTlistedeki küme döndürme işlevi ile :
SELECT generate_series(timestamp '2004-03-07', '2004-08-16', '1 day')::date AS day;
ASAnahtar kelime olup gerekli son varyantta Postgrees sütun diğer adı yanlış anlaşılabilir olurdu dayaksi. Ve olur değil Postgres 10 önce o varyantı tavsiye - en azından değil aynı birden fazla set dönen fonksiyonu ile SELECTlistenin:
(Bu bir yana, son değişken genellikle küçük bir farkla en hızlıdır.)
Neden timestamp [without time zone]?
Çok sayıda aşırı yüklenmiş varyantları vardır generate_series(). Şu anda (Postgres 11):
SELECT oid::regprocedure AS function_signature
, prorettype::regtype AS return_type
FROM pg_proc
where proname = 'generate_series';
function_signature | dönüş_türü
: ------------------------------------------------- ------------------------------- | : --------------------------
generate_series (tamsayı, tamsayı, tamsayı) | tamsayı
generate_series (tamsayı, tamsayı) | tamsayı
create_series (bigint, bigint, bigint) | Bigint
create_series (bigint, bigint) | Bigint
üretme_serisi (sayısal, sayısal, sayısal) | sayısal
create_series (sayısal, sayısal) | sayısal
generate_series (saat dilimi olmadan zaman damgası, saat dilimi olmadan zaman damgası, aralık) | saat dilimi olmayan zaman damgası
generate_series (saat dilimiyle zaman damgası, saat dilimiyle zaman damgası, aralık) | saat dilimli zaman damgası
( numericVaryantlar Postgres 9.5 ile eklenmiştir.) İlgili olanlar son iki uydusu kalın alma ve geri dönen timestamp/ ' timestamptz.
Orada alarak veya dönen hiçbir varyantıdate . Geri dönmek için açık bir kadroya ihtiyaç vardır date. Bağımsız timestampdeğişkenlerle yapılan çağrı, işlev türü çözümleme kurallarına inmeden ve girdi için ek atama yapmadan doğrudan en iyi değişkeni çözer.
timestamp '2004-03-07'tamamen geçerlidir, btw. İhmal edilen zaman bölümü varsayılan olarak 00:00ISO formatındadır.
Fonksiyon tipi çözünürlük sayesinde hala geçebiliriz date. Ancak bu, Postgres'ten daha fazla çalışma gerektirir. Bir yoktur örtülü döküm gelen dateetmek timestamphem de gelen bir dateetmek timestamptz. Belirsiz olurdu, fakat timestamptzedilir "tercih edilen" "tarih / saat türleri" arasında. Böylece maç 4d adımında kararlaştırılır . :
Tüm adayları çalıştırın ve tercih edilen türleri (giriş veri türünün tür kategorisinin) kabul edenleri, tür dönüşümünün gerekli olacağı çoğu konumda tutun. Hiçbiri tercih edilen türleri kabul etmiyorsa tüm adayları saklayın. Yalnızca bir aday kalırsa, onu kullanın; yoksa sonraki adıma geçin.
Fonksiyon tipi çözümlemede ekstra çalışmaya ek olarak, bu, fazladan bir döküm sağlar timestamptz- bu sadece daha fazla maliyet eklemekle kalmaz, aynı zamanda nadir durumlarda beklenmedik sonuçlara yol açan DST ile ilgili sorunlara da yol açabilir. (DST aptalca bir kavramdır, btw, bunu yeterince vurgulayamaz.) İlgili:
Daha pahalı sorgu planını gösteren kemanlara demolar ekledim:
db <> burada fiddle
İlişkili: