我有一个按ID分区的WITH表,并计算用户在特定月份创建的项目数:
| ID | COUNT | MONTH |
------------------------------
| 1 | 1 | 2013-01 |
| 1 | 2 | 2013-05 |
| 2 | 1 | 2013-02 |
| 2 | 2 | 2013-04 |
| 2 | 3 | 2013-06 |
| 3 | 1 | 2013-01 |
在postgresql中,如何将计数添加到缺少的月份以创建这样的最终查询结果?
| ID | COUNT | MONTH |
------------------------------
| 1 | 1 | 2013-01 |
| 1 | 1 | 2013-02 |
| 1 | 1 | 2013-03 |
| 1 | 2 | 2013-04 |
| 1 | 2 | 2013-05 |
| 1 | 3 | 2013-06 |
| 2 | 1 | 2013-02 |
| 2 | 1 | 2013-03 |
| 2 | 2 | 2013-04 |
| 2 | 2 | 2013-05 |
| 2 | 3 | 2013-06 |
| 3 | 1 | 2013-01 |
| 3 | 1 | 2013-02 |
| 3 | 1 | 2013-03 |
| 3 | 1 | 2013-04 |
| 3 | 1 | 2013-05 |
| 3 | 1 | 2013-06 |
答案 0 :(得分:0)
假设MONTH是某种形式的文本字段:
INSERT INTO myTable (id, "count", month)
SELECT t1.id, t1."count", TO_CHAR(r.d, 'YYYY-MM')
FROM myTable as t1
JOIN (SELECT generate_series((min(month) || '-01')::date,
date_trunc('month',now())::date,
'1 month') as d
FROM myTable) AS r
ON (t1.month || '-01')::date < r.d
WHERE NOT EXISTS (
SELECT 1 FROM myTable as t2
WHERE t1.id = t2.id
AND ( (t1."count" < t2."count" AND (t2.month || '-01')::date <= r.d)
OR (t1."count" = t2."count" AND (t2.month || '-01')::date = r.d))
);
使用sqlfiddle here。
答案 1 :(得分:0)
这可以相当简单。
鉴于此表:
CREATE TABLE tbl(id int, ct int, month text);
INSERT INTO tbl (id, ct, month)
VALUES
(1, 1, '2013-01'),
(1, 2, '2013-05'),
(2, 1, '2013-02'),
(2, 2, '2013-04'),
(2, 3, '2013-06'),
(3, 1, '2013-01');
我将ct
替换为函数名count
,我不会将其用作标识符
假设ct
(count)从不低于1并且从不随着给定id
的时间而减少,您可以使用此查询(已更新):
SELECT id.id, max(COALESCE(t.ct, 1)) OVER (PARTITION BY id.id
ORDER BY m.month) AS ct, m.month
FROM generate_series(1,3) id
CROSS JOIN (
SELECT to_char('2013-1-1'::timestamp
+ interval '1 month' * generate_series(0,5), 'YYYY-MM') AS month
) m
LEFT JOIN tbl t USING (id, month)
ORDER BY id, month;
现在延长了几个月的任意时间。