【问题标题】:Count variables per group at time intervals以时间间隔计算每组的变量
【发布时间】:2018-05-17 13:14:38
【问题描述】:

我每隔 10 分钟收集一次车队的数据。以下查询按预期返回 144 行(一天中 10 分钟间隔的数量)。

  select distinct(date_trunc('minute', (((time::timestamp) AT TIME ZONE 'UTC') AT TIME ZONE 'EST'))) FROM fleet_history WHERE (((time::timestamp) AT TIME ZONE 'UTC') AT TIME ZONE 'EST') BETWEEN '2017-11-30 00:00:00'::timestamp AND '2017-11-30 23:59:59'::timestamp ORDER BY date_trunc DESC

fleet_history 表中,还有一个名为repair_state 的列 - 一个字符列,其中包含车辆是“工作”、“维修”还是“其他”的描述。

select * FROM fleet_history limit 5

  id repair_state                time
1  1      working 2017-11-22 15:45:34
2  2    in repair 2017-11-22 15:45:34
3  3      working 2017-11-22 15:45:34
4  4      working 2017-11-22 15:45:34
5  5        other 2017-11-22 15:45:34

我的目标是每隔 10 分钟输出截断的时间,以及工作车辆、维修车辆和其他车辆的数量(计数)(按间隔分组)。

如何在 PostgreSQL 中编写此查询?

【问题讨论】:

  • 将日历表(其记录对应于 10 分钟间隔)左连接到您的 fleet_history 表。然后按间隔聚合以获取计数。
  • 如果你能处理取2017-11-30 00:00:00(常数)和time列之间的差异(以分钟为单位)并将其命名为offset,你可以创建一个列interval = @987654330 @ mod 10。然后,按offsetrepair_state 进行选择计数(*)分组

标签: sql postgresql aggregate


【解决方案1】:

一种方法是创建一个 CTE 日历表,其中包含给定日期的十分钟间隔。然后在时间落在给定的十分钟​​间隔内的条件下,将此日历表加入您的fleet_history 表。最后,对每个区间进行条件聚合,统计各种修复状态。

with calendar as (
    select i from generate_series('2017-11-22', 
    '2017-11-23', '10 minute'::interval) i
)

select
    t1.i,
    sum(case when t2.repair_state = 'working'   then 1 else 0 end) as working_cnt,
    sum(case when t2.repair_state = 'in repair' then 1 else 0 end) as repair_cnt,
    sum(case when t2.repair_state = 'other'     then 1 else 0 end) as other_cnt
from calendar t1
left join fleet_history t2
    on t2.time >= t1.i and t2.time < t1.i + INTERVAL '10 min'
group by
    t1.i
order by
    t1.i;

点击下面的链接查看正在运行的演示。这有点做作,因为您的示例数据仅包含 5 条记录,均来自相同的 10 分钟间隔。

Demo

【讨论】:

    猜你喜欢
    • 2015-12-17
    • 2014-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 2023-01-22
    • 1970-01-01
    相关资源
    最近更新 更多