適切なソリューション
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;
-
LEFT JOIN
を使用する もちろん。 -
generate_series()
タイムスタンプのテーブルをその場で非常に高速に作成できます。 -
一般に、前に集約する方が高速です。 あなたが参加します。私は最近、この関連する回答でsqlfiddle.comにテストケースを提供しました:
- PostgreSQL-配列による順序付け
-
timestamp
をキャストしますdate
(::date
)基本フォーマットの場合。詳細については、to_char()
を使用してください 。 -
GROUP BY 1
最初の出力列を参照するための構文の省略形です。GROUP BY day
の可能性があります 同様ですが、同じ名前の既存の列と競合する可能性があります。またはGROUP BY date_trunc('month', date_col)::date
でもそれは私の好みには長すぎます。 -
date_trunc()
で使用可能な間隔引数を処理します 。 -
count()
NULL
を生成することはありません (0
行なし)、ただしLEFT JOIN
0
を返すにはNULL
の代わりに 外側のSELECT
、COALESCE(some_count, 0) AS some_count
を使用します 。マニュアル。 -
より一般的なソリューションまたは任意の時間間隔の場合 この密接に関連する答えを検討してください:
- Rails+Postgresで任意の時間間隔でレコードをカウントする最良の方法