【问题标题】:Get a rolling count of timestamps in SQL获取 SQL 中时间戳的滚动计数
【发布时间】:2023-12-16 04:12:01
【问题描述】:

我有一个表(在 Oracle 数据库中),看起来类似于下面显示的内容,其中包含大约 4000 条记录。这只是表格设计方式的一个示例。时间戳范围为几年。

|        Time                    |    Action      |
|   9/25/2019 4:24:32 PM         |      Yes       |
|   9/25/2019 4:28:56 PM         |      No        |  
|   9/28/2019 7:48:16 PM         |      Yes       |
|         ....                   |     ....       |

我希望能够获得以 15 分钟滚动间隔发生的时间戳计数。我的主要目标是确定在任何 15 分钟间隔内出现的最大时间戳数。我希望通过查看每个时间戳并获取该时间戳 15 分钟内出现的时间戳计数来完成此操作。

我的目标是拥有类似的东西

|      Interval                             |              Count          |
| 9/25/2019 4:24:00 PM - 9/25/2019 4:39:00  |               2             |
| 9/25/2019 4:25:00 PM - 9/25/2019 4:40:00  |               2             |
|            .....                          |             .....           |
| 9/25/2019 4:39:00 PM - 9/25/2019 4:54:00  |               0             |  

我不确定我将如何做到这一点,如果有的话。任何想法或建议将不胜感激。

【问题讨论】:

  • 我对您如何定义“15 分钟”间隔感到困惑。它不是基于时钟的。
  • 基本上从我的第一个时间戳到我最后一个时间戳是范围。在这两者之间,我想查看每个滚动的 15 分钟间隔。我所说的滚动是指第 0-15 分钟、第 1-16 分钟、第 2-17 分钟……等等。执行此操作需要很长时间,但我需要信息
  • 。 .您应该根据 data 中的时间定义时间间隔。在几年的过程中以 1 分钟的间隔生成时间间隔根本不需要获得您声称想要的最大计数。
  • 我明白了。这样做也很好。

标签: sql oracle date group-by recursive-query


【解决方案1】:

如果您想要数据中的任何 15 分钟间隔,那么您可以使用:

select t.*,
       count(*) over (order by timestamp
                      range between interval '15' minute preceding and current row
                     ) as cnt_15
from t;

如果您想要最大值,请在此使用rank()

select t.*
from (select t.*, rank() over (order by cnt_15 desc) as seqnum
      from (select t.*,
                   count(*) over (order by timestamp
                                  range between interval '15' minute preceding and current row
                                 ) as cnt_15
            from t
           ) t
     ) t
where seqnum = 1;

这不会完全产生您在查询中指定的结果。但它确实回答了这个问题:

我希望能够获得以 15 分钟滚动间隔发生的时间戳计数。我的主要目标是确定在任何 15 分钟间隔内出现的时间戳的最大数量。

【讨论】:

  • 我不熟悉之间的范围。由于某种原因,它不喜欢分钟。它说缺少关键字。我可能错误地将其翻译为我的特定设计。有文档链接吗?
  • @newwebdev22 。 . .哎呀。它缺少 interval 关键字。
  • 嗯是有道理的。我得到了第一个运行。你能解释一下它是如何工作的吗?
  • 我稍微调整了第一个查询以获得我想要的结果。谢谢!
  • @newwebdev22 。 . .这称为窗口子句(在 Oracle 中,我认为更常见的名称是“窗口框架”):docs.oracle.com/cd/E11882_01/server.112/e41084/….
【解决方案2】:

您可以使用递归查询枚举分钟数,然后使用left join 将表带入:

with recursive cte (start_dt, max_dt) as (
    select trunc(min(time), 'mi'), max(time) from mytable
    union all
    select start_dt + interval '1' minute, max_dt from cte where start_dt < max_dt
)
select 
    c.start_dt,
    c.start_dt + interval '15' minute end_dt,
    count(t.time) cnt
from cte c
left join mytable t 
    on  t.time >= c.start_dt 
    and t.time <  c.start_dt + interval '15' minute
group by c.start_dt

【讨论】:

  • 它完成了我的要求,但速度很慢。我已经编辑了我的问题
最近更新 更多