PostgreSQL 根据 table 字段生成月份和年份系列,如果给定月份没有数据,则用空值填充

PostgreSQL generate month and year series based on table field and fill with nulls if no data for a given month

我想生成从当年的下个月(比如 start_month)到 start_month 的 12 个月的一系列月份和年份以及相应的数据(如果有的话,否则 return nulls) 来自 PostgreSQL 中的另一个 table。

SELECT ( ( DATE '2019-03-01' + ( interval '1' month * generate_series(0, 11) ) ) 
         ::  DATE ) dd, 
       extract(year FROM ( DATE '2019-03-01' + ( interval '1' month * 
                                                 generate_series(0, 11) ) 
                         )), 
       coalesce(SUM(price), 0) 
FROM   items 
WHERE  s.date_added >= '2019-03-01' 
       AND s.date_added < '2020-03-01' 
       AND item_type_id = 3 
GROUP  BY 1, 
          2 
ORDER  BY 2; 

上述查询的问题在于它为我提供了所有月份的 price 相同的值。要求是如果给定月份没有 price 数据可用,则 price 列用空值或零填充。

您想在 FROM 子句中加入 generate_series 并加入它,有点像

SELECT months.m::date, ...
FROM generate_series(
        start_month,
        start_month + INTERVAL '11 months',
        INTERVAL '1 month'
     ) AS months(m)
   LEFT JOIN items
      ON months.m::date = items.date_added

generate_series() 放在 FROM 子句中。您正在汇总数据——即计算整个范围内的价格——然后将其预测到所有月份。相反:

SELECT gs.yyyymm,
       coalesce(SUM(i.price), 0) 
FROM generate_series('2019-03-01'::date, '2020-02-01', INTERVAL '1 MONTH'
                    ) gs(yyyymm) LEFT JOIN
     items i
     ON gs.yyyymm = DATE_TRUNC('month', s.date_added) AND
       i.item_type_id = 3 
GROUP BY gs.yyyymm
ORDER BY gs.yyyymm;