【问题标题】:Maximum count of overlapping intervals in PostgreSQLPostgreSQL 中重叠间隔的最大计数
【发布时间】:2020-11-21 19:55:31
【问题描述】:

假设有一个结构如下的表:

id    start      end
--------------------
01    00:18    00:23
02    00:22    00:31
03    00:23    00:48
04    00:23    00:39
05    00:24    00:25
06    00:24    00:31
07    00:24    00:38
08    00:25    00:37
09    00:26    00:42
10    00:31    00:34
11    00:33    00:38

目标是计算在任何给定时刻处于活动状态的总最大行数(即在startend 之间)。使用过程算法会相对简单,但我不确定如何在 SQL 中执行此操作。

根据上面的示例,此最大值将为 8,并且对应于 00:31 时间戳,其中活动行为 2、3、4、6、7、8、9、10(如下面的架构所示)。

获取时间戳和最大值对应的活动行并不重要,只需要实际值本身。

【问题讨论】:

  • 如果我关注你想要在startend 范围内包含0:31 的任何行,对吗?
  • 嗨@AdrianKlaver,有点。我想要重叠间隔的最大计数,不要介意它恰好是特定的时间戳。
  • 那么谁/什么决定什么是活跃的,或者更重要的是比较的价值(例如 00:31)是什么?第一个想法是select count(*) from time_tbl where '00:31'::time between start and end,假设startendtime 字段。
  • 是的,这就是我最初的想法,使用generate_series() 每分钟迭代一次并获取每个活动间隔的计数,然后取最大值。然而,这可以看作是蒙特卡洛抽样的一种形式(每分钟一个样本),我想知道是否可以存在更定量的方式。
  • 我的妹妹,护士,希望轮班时间这么短:) 所以BETWEEN 的想法很有效,它只需要定义时间点的间隔。

标签: postgresql postgresql-11


【解决方案1】:

一开始我在想,使用 generate_series() 每分钟迭代一次并获取每个活动间隔的计数,然后取其最大值。

您可以改进您的想法并仅从表中迭代“开始”值,因为“开始”点之一包括具有最大活动行的时间间隔。

select id, start,
    (select count(1) from tbl t where tbl.start between t.start and t."end")
from tbl;

这里的结果

id  start   count
-----------------
1   00:18:00    1
2   00:22:00    2
3   00:23:00    4
4   00:23:00    4
5   00:24:00    6
6   00:24:00    6
7   00:24:00    6
8   00:25:00    7
9   00:26:00    7
10  00:31:00    8
11  00:33:00    7

因此,此查询为您提供了最大的活动行数

select
    max((select count(1) from tbl t where tbl.start between t.start and t."end"))
from tbl;
max
-----
8

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多