Untuk menghasilkan rangkaian tanggal ini adalah cara yang optimal :
SELECT t.day::date
FROM generate_series(timestamp '2004-03-07'
, timestamp '2004-08-16'
, interval '1 day') AS t(day);
Tambahan date_trunc()
tidak diperlukan. Cast to date
( day::date
) melakukan itu secara implisit.
Tetapi tidak ada gunanya mentransmisikan literal tanggal date
sebagai parameter masukan. Au contraire, timestamp
adalah pilihan terbaik . Keuntungan dalam performa memang kecil, tetapi tidak ada alasan untuk tidak mengambilnya. Dan Anda tidak perlu melibatkan aturan DST (waktu musim panas) yang digabungkan dengan konversi dari date
ke timestamp with time zone
dan ke belakang. Lihat di bawah.
Sintaks pendek yang setara dan kurang eksplisit:
SELECT day::date
FROM generate_series(timestamp '2004-03-07', '2004-08-16', '1 day') day;
Atau dengan fungsi set-return dalam SELECT
daftar:
SELECT generate_series(timestamp '2004-03-07', '2004-08-16', '1 day')::date AS day;
Kata AS
kunci diperlukan dalam varian terakhir, Postgres akan salah menafsirkan alias kolom day
sebaliknya. Dan saya tidak akan menyarankan varian itu sebelum Postgres 10 - setidaknya tidak dengan lebih dari satu fungsi set-return dalam SELECT
daftar yang sama :
(Selain itu, varian terakhir biasanya tercepat dengan selisih kecil.)
Kenapa timestamp [without time zone]
?
Ada sejumlah varian yang kelebihan muatan generate_series()
. Saat ini (Postgres 11):
SELECT oid::regprocedure AS function_signature
, prorettype::regtype AS return_type
FROM pg_proc
where proname = 'generate_series';
function_signature | return_type
: ------------------------------------------------- ------------------------------- | : --------------------------
generate_series (integer, integer, integer) | bilangan bulat
generate_series (integer, integer) | bilangan bulat
generate_series (bigint, bigint, bigint) | bigint
generate_series (bigint, bigint) | bigint
generate_series (numerik, numerik, numerik) | numerik
generate_series (numerik, numerik) | numerik
generate_series (timestamp tanpa zona waktu, timestamp tanpa zona waktu, interval) | stempel waktu tanpa zona waktu
generate_series (stempel waktu dengan zona waktu, stempel waktu dengan zona waktu, interval) | stempel waktu dengan zona waktu
( numeric
varian ditambahkan dengan Postgres 9.5.) Yang relevan adalah dua yang terakhir dalam pengambilan dan pengembalian timestamp
/ timestamptz
.
Tidak ada varian yang mengambil atau kembalidate
. Pemeran eksplisit diperlukan untuk kembali date
. Panggilan dengan timestamp
argumen menyelesaikan ke varian terbaik secara langsung tanpa turun ke aturan resolusi jenis fungsi dan tanpa cast tambahan untuk input.
timestamp '2004-03-07'
sangat valid, btw. Bagian waktu yang dihilangkan secara default 00:00
dengan format ISO.
Berkat fungsi jenis resolusi kita masih bisa lewat date
. Tapi itu membutuhkan lebih banyak pekerjaan dari Postgres. Ada pemeran implisit dari date
ke timestamp
serta dari date
ke timestamptz
. Akan ambigu, tetapi timestamptz
adalah "disukai" antara "jenis tanggal / waktu". Jadi pertandingan diputuskan pada langkah 4d. :
Jalankan melalui semua kandidat dan pertahankan mereka yang menerima tipe yang disukai (dari kategori tipe tipe data input) di posisi paling banyak di mana konversi tipe akan diperlukan. Pertahankan semua kandidat jika tidak ada yang menerima jenis yang disukai. Jika hanya satu calon yang tersisa, gunakanlah; jika tidak lanjutkan ke langkah berikutnya.
Selain pekerjaan ekstra dalam resolusi jenis fungsi, ini menambahkan pemeran tambahan timestamptz
- yang tidak hanya menambah biaya, tetapi juga dapat menyebabkan masalah dengan DST yang mengarah ke hasil yang tidak terduga dalam kasus yang jarang terjadi. (DST adalah konsep tolol, btw, tidak bisa cukup menekankan hal ini.)
Saya menambahkan demo ke biola yang menunjukkan paket kueri yang lebih mahal:
db <> biola di sini
Terkait: