【问题标题】:Select query for fetching data on the interval of 4 hours选择以 4 小时为间隔获取数据的查询
【发布时间】:2017-06-12 20:22:09
【问题描述】:

我正在使用 postgres 8.1 数据库,我想编写一个查询,以 4 小时的间隔选择数据。

因此,如图所示,subscriber_id 带有日期,这是数据库中当前可用数据的方式和

我想要这样的数据

No. of Subscriber |  Interval
      0               0-4
      0               4-8
      7               8-12
      1               12-16
      0               16-20
      0               20-24

基本上每天我们有 24 小时,如果我除以 24/4=6 意味着我每天总共有 6 个间隔

0-4
4-8
8-12
12-16
16-20
20-24

所以我需要这些时间间隔内的订阅者数量。 postgres 中是否有任何数据函数可以解决我的问题,或者我如何为这个问题编写查询?

注意:请根据 postgres 8.1 版本编写您的解决方案

【问题讨论】:

    标签: postgresql date time count intervals


    【解决方案1】:

    使用generate_series() 生成句点并使用适当的句点左连接date_time,例如:

    with my_table(date_time) as (
    values
    ('2016-10-24 11:10:00'::timestamp),
    ('2016-10-24 11:20:00'),
    ('2016-10-24 15:10:00'),
    ('2016-10-24 21:10:00')
    )
    
    select 
        format('%s-%s', p, p+4) as "interval", 
        sum((date_time notnull)::int) as "no of subscriber"
    from generate_series(0, 20, 4) p
    left join my_table
    on extract(hour from date_time) between p and p+ 4
    group by p
    order by p;
    
     interval | no of subscriber 
    ----------+------------------
     0-4      |                0
     4-8      |                0
     8-12     |                2
     12-16    |                1
     16-20    |                0
     20-24    |                1
    (6 rows)    
    

    我不认为有一个活着的人记得版本 8.1。你可以试试:

    create table periods(p integer);
    insert into periods values (0),(4),(8),(12),(16),(20);
    
    select 
        p as "from", p+4 as "to", 
        sum((date_time notnull)::int) as "no of subscriber"
    from periods
    left join my_table
    on extract(hour from date_time) between p and p+ 4
    group by p
    order by p;
    
     from | to | no of subscriber 
    ------+----+------------------
        0 |  4 |                0
        4 |  8 |                0
        8 | 12 |                2
       12 | 16 |                1
       16 | 20 |                0
       20 | 24 |                1
    (6 rows)    
    

    【讨论】:

    • generate_series 在 postgres 8.1 版本中不可用
    【解决方案2】:

    在 Postgres 中,您可以通过为您的时间段生成所有间隔来做到这一点。这有点棘手,因为您必须在数据中挑选出日期。不过,generate_series() 真的很有帮助。

    剩下的只是一个left join和聚合:

    select dt.dt, count(t.t)
    from (select generate_series(min(d.dte), max(d.dte) + interval '23 hour', interval '4 hour') as dt
          from (select distinct date_trunc('day', t.t)::date as dte from t) d 
         ) dt left join
         t
        on t.t >= dt.dt and t.t < dt.dt + interval '4 hour'
    group by dt.dt
    order by dt.dt;
    

    请注意,这会将期间保留为期间开始的日期/时间。如果这更有帮助,您可以轻松地将其转换为日期和间隔数。

    【讨论】:

    • 感谢您的回答,查询有点混乱,请您编辑它并使用表名作为打开和列名subscribed
    • @KushalJain:如果您将示例数据发布为可以复制的文本,而不是screen shot,Gordon 可能会这样做
    • 是的,但有人可以做到。我真的不明白,哪个是可变的,哪个是列
    • 我认为 generate_series 函数在一些更高版本的 postgres 中可用。我使用的是 8.1 版本
    • @KushalJain 。 . . Postgres 8.1 于 12 年前发布。您可能需要考虑升级。
    【解决方案3】:

    我认为如果您知道时间间隔(下限和上限),因此运行六个不同的查询会更好。

    【讨论】:

      猜你喜欢
      • 2020-09-10
      • 1970-01-01
      • 2019-07-05
      • 2018-09-16
      • 1970-01-01
      • 2014-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多