Postgres 生成系列
Posted
技术标签:
【中文标题】Postgres 生成系列【英文标题】:Postgres generate_series 【发布时间】:2011-10-31 12:46:18 【问题描述】:我想要对表格进行统计,为此我使用generate_series();
这是我正在做的:
SELECT x.month, amount
FROM (SELECT generate_series(
min(date_trunc('month', date)),
max(date_trunc('month', date)),
'1 month'
) AS month
FROM table
WHERE user_id = 55 AND ...
) x
LEFT JOIN (
SELECT SUM(amount) AS amount, date_trunc('month', date) AS month
FROM table
WHERE user_id = 55 AND ...
GROUP BY month
) q ON q.month = x.month
ORDER BY month
这很好用,但是当我想应用过滤器(例如获取特定用户的金额)时,我必须应用它们两次。有没有办法避免过滤两次,或者以更有效的方式重写它,因为我不确定这是否是正确的做法?
【问题讨论】:
【参考方案1】:您可以为此写WITH
query:
WITH month_amount AS
(
SELECT
sum(amount) AS amount,
date_trunc('month', date) AS month
FROM Amount
WHERE user_id = 55 -- AND ...
GROUP BY month
)
SELECT month, amount
FROM
(SELECT generate_series(min(month), max(month), '1 month') AS month
FROM month_amount) x
LEFT JOIN month_amount
USING (month)
ORDER BY month;
示例结果:
SELECT * FROM amount WHERE user_id = 55;
amount_id | user_id | amount | date
-----------+---------+--------+------------
3 | 55 | 7 | 2011-03-16
4 | 55 | 5 | 2011-03-22
5 | 55 | 2 | 2011-05-07
6 | 55 | 18 | 2011-05-27
7 | 55 | 4 | 2011-06-14
(5 rows)
WITH month_amount ..
month | amount
------------------------+--------
2011-03-01 00:00:00+01 | 12
2011-04-01 00:00:00+02 |
2011-05-01 00:00:00+02 | 20
2011-06-01 00:00:00+02 | 4
(4 rows)
【讨论】:
我从没想过 CTE,但它们真的很有用。非常感谢,它很完美。 +1 我学到了一些我不知道的关于 postgres 的东西 - 谢谢 :) 如何生成系列,如 select m from generate_series(01,12) m output :01, 02 , 03 , 04, 05, 06, 07, 08 ,09, 10 ,11, 12跨度> 【参考方案2】:您可以在 WITH 子句中执行查询,然后使用 SELECT 来添加缺失的月份:
WITH query AS (
SELECT SUM(amount) AS amount, date_trunc('month', date) AS month
FROM table
WHERE user_id = 55 AND ...
GROUP BY month
)
SELECT date(d.month) AS month, q.amount
FROM (
SELECT generate_series(min(month), max(month), '1 month') AS month
FROM query
) d
LEFT JOIN query q ON q.month = d.month
ORDER BY month
【讨论】:
以上是关于Postgres 生成系列的主要内容,如果未能解决你的问题,请参考以下文章
使用 postgres generate_series 生成定期计划
在传递给Postgres之前使用Postgres默认值或生成它们是更好的做法吗?
如何在超过 12 的 postgres 版本上自动生成 Oid