【问题标题】:How to get an average of timestamps? PostgreSQL如何获得时间戳的平均值? PostgreSQL
【发布时间】:2017-05-10 01:35:36
【问题描述】:

我目前正在使用这个:

select avg(tank_level)
from (
    select row_number() over (order by id) as rn, tank_level
    from data_tanksensor
    where sensors_on_site_id = 91
) s
group by (rn + ((Select count(*)/10 From data_tanksensor where sensors_on_site_id = 91)-1))/ (Select count(*)/10 From data_tanksensor where sensors_on_site_id = 91)
;  

从一个表中获取 10 个平均值。该表还包含时间戳,我想获取 10 个平均 tank_level 中的每一个的平均时间戳。这用于创建历史图表。如果有人可以帮助我修改此查询以获得平均时间戳,我们将不胜感激。提前致谢。

表格是这样的

. id sensors_on_site_id tank_level timestamps [PK] bigint integer double precision time without time zone ........... .................. ................ ...................... 12345 91 7.5 2017-03-24 11:16:31.143362 12346 91 7.6 2017-03-24 11:21:31.148639 12347 91 5.4 2017-03-24 11:26:31.155739 12348 91 3.6 2017-03-24 11:31:31.156478 12349 91 8.5 2017-03-24 11:36:31.157303 12350 91 4.2 2017-03-24 11:41:31.172008 例如,如果我只想从中取平均值,我的原始查询将是

select avg(tank_level) from ( select row_number() over (order by id) as rn, tank_level from data_tanksensor where sensors_on_site_id = 91 ) s group by (rn + ((Select count(*)/2 From data_tanksensor where sensors_on_site_id = 91)-1))/ (Select count(*)/2 From data_tanksensor where sensors_on_site_id = 91) ; 粗略的查询缺少将平均时间戳的部分,这是我想要弄清楚的。但我想要得到的预期结果是

avg timestamp double precision timestamp without time zone ................ ........................... 6.833333 2017-03-24 11:21:31... 5.433333 2017-03-24 11:36:31... 同样,这只是示例数据,一次平均的行数为数百。谢谢

【问题讨论】:

  • 请编辑您的问题并提供示例数据和所需结果。
  • F.ex. to_timestamp(avg(extract(epoch from timestamp_col)))?

标签: sql database postgresql


【解决方案1】:

您可以将时间戳转换为 unix 时间戳,将值相加,除以值的数量,然后再转换回时间戳。一个简单的工作示例:

with
    __ts as(
        select unnest(array[
            '2015-11-22 09:31:00', '2015-11-22 09:32:00', '2015-11-23 11:31:00', '2015-11-23 11:32:00',
            '2015-11-23 11:34:00', '2015-11-23 15:28:00', '2015-11-23 15:29:00', '2015-11-24 10:49:00',
            '2015-11-24 10:50:00', '2015-11-24 11:18:00'
        ]::timestamp without time zone[]) as ts
    )
select
    to_timestamp(sum(extract(epoch from ts)) / (select count(1) from __ts))
from
    __ts

【讨论】:

  • Unix 时间戳(又名double precision)可以直接取平均值(avg()),不需要手动计算sum() / count()(特别是因为count()可以返回零,所以相当于 -- 更麻烦 -- sum() / nullif(count(), 0))
  • @pozs 是的,这对我来说很愚蠢。好收获
【解决方案2】:

select to_timestamp(avg(timestamps)) "timestamps", avg(tank_level) "TankLevel" from ( select row_number() over (order by id) as rn, tank_level, extract(epoch from timestamps) "timestamps" from data_tanksensor where sensors_on_site_id = 91 ) s group by (rn + ((Select count(*)/10 From data_tanksensor where sensors_on_site_id = 91)-1))/ (Select count(*)/10 From data_tanksensor where sensors_on_site_id = 91) order by timestamps asc ; 弄清楚了 谢谢大家的例子

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-29
    • 2018-03-14
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2020-09-11
    • 2020-10-11
    • 1970-01-01
    相关资源
    最近更新 更多