【问题标题】:Select continuous time intervals in SQL在 SQL 中选择连续的时间间隔
【发布时间】:2021-06-29 19:24:17
【问题描述】:

我有日期时间表,我需要选择连续的时间间隔

我的桌子:

Id Time
1 2021-01-01 10:00:00
1 2021-01-01 10:01:00
1 2021-01-01 10:02:00
1 2021-01-01 10:04:00
2 2021-01-01 10:03:00
2 2021-01-01 10:04:00
2 2021-01-01 10:06:00
2 2021-01-01 10:07:00

我需要的结果:

id date_from date_to
1 2021-01-01 10:00:00 2021-01-01 10:02:00
1 2021-01-01 10:04:00 2021-01-01 10:04:00
2 2021-01-01 10:03:00 2021-01-01 10:04:00
2 2021-01-01 10:06:00 2021-01-01 10:07:00

我试过这样,但做不到

select id, 
  min(date_from) over 
    (partition by id, date_to 
       order by id) 
    as date_from, 
    max(date_to) over 
      (partition by id, date_from 
      order by id) 
    as date_to
    from (
      select id, 
      MIN(time) over 
        (PARTITION by id, 
        diff2 between 0 and 60
        ORDER BY id, time) 
      as date_from, 
      max(MINUTE) over 
        (PARTITION by id, 
        diff between 0 and 60
        ORDER BY id, time) 
      as date_to 
        from (
           select *, 
           unix_timestamp(date_lead) - unix_timestamp(time) 
              as diff, 
           unix_timestamp(time) - unix_timestamp(date_lag) 
              as diff2 
                    from (
                        select id, time,
                            NVL(LEAD(time) over 
                                (PARTITION by id 
                                ORDER BY id, time), time) 
                            as date_lead,
                            NVL(LAG(time) over 
                                (PARTITION by id 
                                ORDER BY id, time), time) 
                            as date_lag
                        from my_table) 
                    )
                )

【问题讨论】:

  • 您在使用 Oracle 吗?如果是这样,请使用您的实际数据库更新您问题下的标签。

标签: sql postgresql


【解决方案1】:

假设您的时间戳是精确的(没有秒或几分之一秒),您可以从time 列中减去枚举的分钟数。这是“相邻”行的常量:

select id, min(time), max(time)
from (select t.*,
             row_number() over (partition by id order by time) as seqnum
      from t
     ) t
group by id, time - seqnum * interval '1 minute';

如果您有秒和小数秒,那么您可能需要使用date_trunc() 调整逻辑。如果这是一个问题,我建议您提出一个问题,并提供适当的样本数据和所需的结果。

【讨论】:

    【解决方案2】:
    select id, MIN(time), max(time) from 
        (SELECT * interval '1 minutes' *-1* (DENSE_RANK() OVER (PARTITION BY id ORDER by time) ) + TO_TIMESTAMP(time, 'YYYY-MM-DD HH24:MI:SS') as drank 
    from event) t1                                      
    GROUP by drank, id
    order by id
    

    【讨论】:

    • 您好,请对您的代码添加一些解释(即使是内联 cmets 也很有帮助!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    相关资源
    最近更新 更多