繁体   English   中英

根据时间间隔分组计算平均值

[英]calculating average with grouping based on time intervals

在postgres表中,我以10秒的间隔存储了对象的速度。 一天中每10秒钟都无法使用这些值; 所以今天可能没有线16:39:40

假设不存在的行表示速度为0,则查询看起来如何获得包含给定日期1分钟(或30秒或n秒)间隔的平均值的关系。

speed_table
id( int ,pk)ts(时间戳)速度(数值)

我已经建立了这个查询,但是在一些重要的部分上卡住了:

SELECT 
    date_trunc('minute', ts) AS truncated, 
    avg(speed)
FROM speed_table AS t 
WHERE ts >= '2014-06-21 00:00:00'
AND ts <= '2014-06-21 23:59:59'
AND condition2 = 'something'
GROUP BY date_trunc('minute', ts)
ORDER BY truncated
  • 除了date_trunc函数的结果外,如何更改间隔(例如30分钟的5分钟)?
  • 如何添加当天剩余时间的不可用行?

此特定示例的简单快速解决方案:

SELECT date_trunc('minute', ts) AS minute
     , sum(speed)/6 AS avg_speed
FROM   speed_table AS t 
WHERE  ts >= '2014-06-21 0:0'
AND    ts <  '2014-06-20 0:0'  -- exclude dangling corner case
AND    condition2 = 'something'
GROUP  BY 1
ORDER  BY 1;

您需要将缺少的行作为“ 0速度”考虑在内。 由于一分钟有6个样本,因此只需将它们相加并除以6。丢失的行将隐式评估为0

这将在几分钟之内不返回任何行,根本没有任何行。 缺少结果行的avg_speed0

一般查询任意间隔

适用于date_trunc()手册中列出的所有间隔:

SELECT date_trunc('minute', g.ts) AS ts_start
     , avg(COALESCE(speed, 0))    AS avg_speed
FROM  (SELECT generate_series('2014-06-21 0:0'::timestamp
                            , '2014-06-22 0:0'::timestamp
                            , '10 sec'::interval) AS ts) g
LEFT   JOIN speed_table t USING (ts)
WHERE (t.condition2 = 'something' OR
       t.condition2 IS NULL)                -- depends on actual condition!
AND    g.ts <> '2014-06-22 0:0'::timestamp  -- exclude dangling corner case
GROUP  BY 1
ORDER  BY 1;

有问题的部分是其他未知条件。 您需要定义它。 并确定generate_series提供的缺少的行是否应该通过测试(这很棘手!)。
我让它们通过我的示例(以及所有其他带有NULL值的行)。

相比:
PostgreSQL:“按分钟”运行查询的行数

任意间隔:
将时间戳截断为任意间隔

对于完全任意的间隔,请考虑基于纪元值的 width_bucket() 数学或使用经常被忽略的函数width_bucket() 例:
聚集PostgreSQL中的 (x,y)坐标点云聚集 PostgreSQL中的 (x,y)坐标点云

如果您发布了一些数据,则可以进行测试,以便包含错误。 指出它们,包括错误消息,以便我修复。

select
    to_timestamp(
        (extract(epoch from ts)::integer / (60 * 2)) * (60 * 2)
    ) as truncated,
    avg(coalesce(speed, 0)) as avg_speed
from
    generate_series (
        '2014-06-21 00:00:00'::timestamp,
        '2014-06-22'::timestamp - interval '1 second',
        '10 seconds'
    ) ts (ts)
    left join
    speed_table t on ts.ts = t.ts and condition2 = 'something'
group by 1
order by 1

该示例按30秒分组。 它是自1970-01-01 00:00:00epoch )以来的1970-01-01 00:00:00除以120。如果要分组5分钟,则将其除以12(60/5)。

该示例中的generate_series以1秒的间隔生成时间戳。 它与速度表left outer join ,从而填补了空白。 当速度为零时,合并返回0。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM