0

我有一个 WITH 表,它按 id 分区并计算用户在某个月份创建的项目数:

|      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 |
4

2 回答 2

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 。

于 2013-06-10T19:21:02.413 回答
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;

现在延长了任意系列的几个月。

->SQLfiddle

于 2013-06-10T20:28:10.753 回答