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

标签 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 天以上的情况。

最佳答案

这里的特殊困难是您需要在聚合行后 计算天数。您可以使用 窗口函数 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 应该应用于外部查询。

关于sql - 根据数据汇总今天和前一天的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20746360/

相关文章:

sql - PostgreSQL 错误 : query has no destination for result data

MySQL 在 Select .. In 语句中排序

php - 命令不同步;你现在不能运行这个命令

sql - 使用 CTE 对查询结果进行分组

sql - 在 postgresql 查询中检查 bool 值 true/false 结果

javascript - 如何在 odoo 8 中重写 js 函数?

PostgreSQL,按值分组

python - 运行 pgadmin 抛出意外错误

sql - MAX()和MAX()OVER PARTITION BY在Teradata查询中产生错误3504

带有 WHERE IN 子句的 SQL MAX 日期