Solusi yang tepat
SELECT *
FROM (
SELECT day::date
FROM generate_series(timestamp '2007-12-01'
, timestamp '2008-12-01'
, interval '1 month') day
) d
LEFT JOIN (
SELECT date_trunc('month', date_col)::date AS day
, count(*) AS some_count
FROM tbl
WHERE date_col >= date '2007-12-01'
AND date_col <= date '2008-12-06'
-- AND ... more conditions
GROUP BY 1
) t USING (day)
ORDER BY day;
-
Gunakan
LEFT JOIN, tentu saja. -
generate_series()dapat menghasilkan tabel stempel waktu dengan cepat, dan sangat cepat. -
Biasanya lebih cepat untuk mengagregasi sebelum Anda bergabung. Saya baru-baru ini memberikan kasus uji di sqlfiddle.com dalam jawaban terkait ini:
- PostgreSQL - urutkan menurut larik
-
Keluarkan
timestampuntukdate(::date) untuk format dasar. Untuk lebih banyak gunakanto_char(). -
GROUP BY 1adalah singkatan sintaks untuk referensi kolom output pertama. Bisa jadiGROUP BY dayjuga, tapi itu mungkin bertentangan dengan kolom yang ada dengan nama yang sama. AtauGROUP BY date_trunc('month', date_col)::datetapi itu terlalu panjang untuk seleraku. -
Bekerja dengan argumen interval yang tersedia untuk
date_trunc(). -
count()tidak pernah menghasilkanNULL(0tanpa baris), tetapiLEFT JOINtidak.
Untuk mengembalikan0bukannyaNULLdi bagian luarSELECT, gunakanCOALESCE(some_count, 0) AS some_count. Panduan. -
Untuk solusi yang lebih umum atau interval waktu yang berubah-ubah pertimbangkan jawaban yang terkait erat ini:
- Cara terbaik untuk menghitung catatan dengan interval waktu sewenang-wenang di Rails+Postgres