web-dev-qa-db-ja.com

generate_series()からのレコードセットで欠落している日付を埋める

考慮してください:

with days as (select day::date
from generate_series(date '2013-01-01', date '2013-01-01' + 365, interval '1 day' day) day
) 
select 'Inspections'::text as data_label,
count(i.reporting_id) as daily_count, d.day as date_column
from days d
left join inspection i on i.close_case_date = d.day
group by d.day
order by d.day

これにより、次のようなセットが返されます。

data_label | daily_count | date_column
Inspections    1           01/01/13
Inspections    2           01/02/13
Inspections    4           01/04/13
Inspections    8           01/06/13

レコードセットの1日と2日のギャップに注意してください。私はそれらの値を0で埋めたセットを生成する必要があります:

data_label | daily_count | date_column
Inspections    1           01/01/13
Inspections    2           01/02/13
Inspections    0           01/03/13
Inspections    4           01/04/13
Inspections    0           01/05/13
Inspections    8           01/06/13

どうすればいいですか?私はデータベース開発者ではなく、Postgresを初めて使用するため、どこから始めればよいかわからず、この目的を達成する方法について何も見つけることができません。

4
Mr. Concolato

これはある種の誤解です。あなたの質問のクエリはあなたが求めているものをすでに返しています。細かい部分のみ変更しました:

_SELECT 'Inspections'::text   AS data_label
     , count(i.reporting_id) AS daily_count
     , d.day                 AS date_column
FROM  (
   SELECT generate_series(timestamp '2013-01-01'
                        , timestamp '2013-01-01' + interval '1 year - 1 day'
                        , interval '1 day')::date
   ) d(day)
LEFT   JOIN inspection i ON i.close_case_date = d.day
GROUP  BY d.day
ORDER  BY d.day;
_

一連の日付の生成について:

マイナーポイント

  • _date '2013-01-01' + interval '1 year - 1 day'_は、うるう年もカバーするために_date '2013-01-01' + 365_より優れています。

  • 安価なサブクエリを使用します。 CTEは必要ありません。

  • なぜあなたはcount(i.reporting_id)なのですか? iの行を数えるには、すでに結合しているcount(i.close_case_date)を使用します。

11
with days as (select day::date
from generate_series(date '2013-01-01', date '2013-01-01' + 3, interval '1 

day' day) day
),
inspection as (select date '2013-01-01' AS close_case_date 
UNION ALL select date '2013-01-03')
select 
(SELECT COUNT(*) 
  FROM inspection AS i WHERE i.close_case_date = d.day) AS daily_count, 
d.day as date_column
from days d



1;"2013-01-01"
0;"2013-01-02"
1;"2013-01-03"
0;"2013-01-04"
1
A-K