PostgreSQL中的时间序列 - 列出更改

时间:2014-10-08 15:37:06

标签: postgresql aggregate-functions window-functions

我在PostgreSQL中有一个带有一些时间序列数据的表,显示参数中值的变化 - 我们可以假设没有间隙,并且每个date_to都有一个对应的date_from(除了最后一个当然):

select date_from, date_to, xx from yy order by date_from asc;

date_from  |  date_to   |               xx
-----------+------------+------------------
2014-05-01 | 2014-05-21 |                0
2014-05-21 | 2014-06-02 |               10
2014-06-02 | 2014-06-05 |               10
2014-06-05 | 2014-06-10 |               10
2014-06-10 | 2014-06-26 |                0
2014-06-26 | 2014-07-01 |               10
2014-07-01 | 2014-07-08 |               10
2014-07-08 | 2014-07-23 |                0
2014-07-23 | 2014-08-04 |               10
2014-08-04 | 2014-08-20 |               10
2014-08-20 | 2014-09-02 |               20
2014-09-02 | 2014-09-03 |               20
2014-09-03 | 2014-09-22 |                0
2014-09-22 | 2014-09-24 |               10
2014-09-24 | 2014-10-02 |               20
2014-10-02 | 2014-10-08 |               20
2014-10-08 | infinity   |                0

我的目标是按时间间隔汇总数据,并显示xx期间保持给定值的时间段:

date_from  |  date_to   |               xx
-----------+------------+------------------
2014-05-01 | 2014-05-21 |                0
2014-05-21 | 2014-06-10 |               10
2014-06-10 | 2014-06-26 |                0
2014-06-26 | 2014-07-08 |               10
2014-07-08 | 2014-07-23 |                0
2014-07-23 | 2014-08-20 |               10
2014-08-20 | 2014-09-03 |               20
2014-09-03 | 2014-09-22 |                0
2014-09-22 | 2014-09-24 |               10
2014-09-24 | 2014-10-08 |               20
2014-10-08 | infinity   |                0

为了以更紧凑的方式向某些商业用户展示这些数据,我尝试使用window functions,但我没有找到如何隔离这些更改。那里有人有提示吗?

谢谢,

1 个答案:

答案 0 :(得分:1)

您可以使用运行总计功能来创建组标识符,如下所示:

WITH yy(date_from,date_to,xx) AS (
  VALUES ('2014-05-01'::date,'2014-05-21'::date,0),
    ('2014-05-21','2014-06-02',10),
    ('2014-06-02','2014-06-05',10),
    ('2014-06-05','2014-06-10',10),
    ('2014-06-10','2014-06-26',0),
    ('2014-06-26','2014-07-01',10),
    ('2014-07-01','2014-07-08',10),
    ('2014-07-08','2014-07-23',0),
    ('2014-07-23','2014-08-04',10),
    ('2014-08-04','2014-08-20',10),
    ('2014-08-20','2014-09-02',20),
    ('2014-09-02','2014-09-03',20),
    ('2014-09-03','2014-09-22',0),
    ('2014-09-22','2014-09-24',10),
    ('2014-09-24','2014-10-02',20),
    ('2014-10-02','2014-10-08',20),
    ('2014-10-08','infinity',0)
)
SELECT date_from,date_to,xx,
       sum(g) OVER (ORDER BY date_from) grp
  FROM (
    SELECT date_from,date_to,xx,
           CASE WHEN lag(xx) OVER (ORDER BY date_from) = xx THEN NULL ELSE 1 END g
      FROM yy) s
 ORDER BY date_from;

只要您有新列grp,就可以将其用于GROUP BY。 注意,这里需要子查询,否则不能引用窗口函数的结果。

请检查此related question