根据数据汇总今天和前一天的汇总数据

时间:2013-12-23 15:20:15

标签: sql postgresql aggregate-functions common-table-expression window-functions

无法整理查询以提取给定时间戳的聚合值以及之前的时间戳。给出以下架构:

name TEXT, 
ts TIMESTAMP, 
X NUMERIC, 
Y NUMERIC

由于数据缺口,ts列中存在空白,我正在尝试构建一个查询来生成

name, 
date_trunc('day' q1.ts), 
avg(q1.X), 
sum(q2.Y), 
date_trunc('day', q2.ts), 
avg(q2.X), 
sum(q2.Y)

上半场很简单:

SELECT q1.name, date_trunc('day', q1.ts), avg(q1.X), sum(q1.Y)
FROM data as q1
GROUP BY 1, 2
ORDER BY 1, 2;

但不确定如何生成关系以找到每行之前的“日”。我正在尝试这样的内部联接:

SELECT q1.name, q1.day, q1.avg, q1.sum, q2.day, q2.avg, q2.sum
FROM (
    SELECT name, date_trunc('day', ts) AS day, avg(X) AS avg, sum(Y) as sum
    FROM data
    GROUP BY 1,2
    ORDER BY 1,2
) q1 INNER JOIN (
    SELECT name, date_trunc('day', ts) AS day, avg(X) AS avg, sum(Y) as sum
    FROM data
    GROUP BY 1,2
    ORDER BY 1,2
) q2 ON (
    q1.name = q2.name 
    AND  q2.day = q1.day - interval '1 day'
);

问题在于,它不包括下一个“日”在当天之前超过1天的情况。

2 个答案:

答案 0 :(得分:2)

这里的特殊困难是您需要在聚合行后数天。您可以使用窗口函数row_number() 在单个查询级别执行此操作,因为窗口函数在GROUP BY 聚合之后应用。

另外,使用CTE避免多次执行相同的子查询:

WITH q AS (
    SELECT name, ts::date AS day
          ,avg(x) AS avg_x, sum(y) AS sum_y
          ,row_number() OVER (PARTITION BY name ORDER BY ts::date) AS rn
    FROM   data
    GROUP  BY 1,2
   )
SELECT q1.name, q1.day, q1.avg_x, q1.sum_y
      ,q2.day AS day2, q2.avg_x AS avg_x2, q2.sum_y AS sum_y2
FROM   q      q1
LEFT   JOIN q q2 ON q1.name = q2.name 
                AND q1.rn   = q2.rn + 1
ORDER  BY 1,2;

使用更简单的演员陈述(ts::date)代替date_trunc('day', ts)来获得“天”。
LEFT [OUTER] JOIN(与[INNER] JOIN相对)有助于保留第一行的角落情况,前一天没有。 ORDER BY应该应用于外部查询。

答案 1 :(得分:1)

问题不是很清楚,但听起来你实际上是在试图填补空白,同时跟踪领先/滞后的行。

要填补空白,请查看generate_series(),然后将其与表格一起加入:

select d
from generate_series(timestamp '2013-12-01', timestamp '2013-12-31', interval '1 day') d;

http://www.postgresql.org/docs/current/static/functions-srf.html

对于上一行和下一行值,请查看lead()lag()窗口函数:

select date_trunc('day', ts) as curr_row_day,
       lag(date_trunc('day', ts)) over w as prev_row_day
from data
window w as (order by ts)

http://www.postgresql.org/docs/current/static/tutorial-window.html