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;
我想生成从当年的下个月(比如 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;