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 date
girdi parametresi olarak dönüştürmenin de bir anlamı yoktur . Au contraire, timestamp
en 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ı, date
arasında timestamp with time zone
ve 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 SELECT
listedeki küme döndürme işlevi ile :
SELECT generate_series(timestamp '2004-03-07', '2004-08-16', '1 day')::date AS day;
AS
Anahtar kelime olup gerekli son varyantta Postgrees sütun diğer adı yanlış anlaşılabilir olurdu day
aksi. Ve olur değil Postgres 10 önce o varyantı tavsiye - en azından değil aynı birden fazla set dönen fonksiyonu ile SELECT
listenin:
(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ı
( numeric
Varyantlar 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 timestamp
değ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:00
ISO 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 date
etmek timestamp
hem de gelen bir date
etmek timestamptz
. Belirsiz olurdu, fakat timestamptz
edilir "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: