当前位置: 首页 > 面试题库 >

PostgreSQL查询以检测重叠的时间范围

马嘉勋
2023-03-14
问题内容

我在PostgreSQL 9.2中有一张表,看起来像这样(简化):

CREATE TABLE my_features
(
  id integer NOT NULL,
  feature_id integer NOT NULL,
  begin_time timestamp NOT NULL,
  end_time timestamp
)

对于每个feature_id,可能会有多行,其时间范围由begin_time /
end_time指定。它们可能重叠,但这是相对罕见的。我正在寻找一种快速的方法来查找所有具有/不具有 任何 重叠的feature_id 。

我尝试使用窗口函数来执行此操作,如下所示:

SELECT feature_id, bool_or(end_time > lead(begin_time) OVER ts_win) OVER ts_win AS overlaps_any
FROM my_features
WINDOW ts_win AS (PARTITION BY feature_id ORDER BY begin_time)

…但这是行不通的:

ERROR:  window function calls cannot be nested

该算法很简单:按begin_time排序给定feature_id的行,并检查是否有end_time>下一个begin_time(如果有)。我怀疑必须有一种简单的方法可以执行此操作,也许使用tsrange函数,但是似乎暂时找不到它。


问题答案:

实际上,可以使用范围类型来完成此操作。

下面将选择所有具有重叠范围的行:

select f1.*
from my_features f1
where exists (select 1
              from my_features f2
              where tsrange(f2.begin_time, f2.end_time, '[]') && tsrange(f1.begin_time, f1.end_time, '[]')
                and f2.feature_id = f1.feature_id
                and f2.id <> f1.id);

当您将条件更改为时,NOT EXISTS您会发现那些没有任何重叠范围的条件。

SQLFiddle示例:http
://sqlfiddle.com/#!15/40b1e/1

tsrange(f2.begin_time, f2.end_time, '[]')创建一个包含上限和下限的范围。您还可以创建排除一个或两个范围的范围。

可以在手册中找到更多详细信息:http :
//www.postgresql.org/docs/current/static/rangetypes.html#RANGETYPES-
INCLUSIVITY

&&操作者检查是否两个范围重叠:http://www.postgresql.org/docs/current/static/functions-
range.html

(我只是希望甲骨文喜欢这样的东西…)



 类似资料:
  • 我们有一个Postgres表(物化视图),其中包含大约200万行,列如下: start_time(timestampz)-有索引 end_time(timestampz)-有索引 对于表中的每一行,我们希望添加一个包含以下内容的结果列: 1,如果行开始和结束时间范围与任何其他行重叠 0,如果行开始和结束时间范围不与任何其他行重叠 将每一行标记为具有重叠(1或0)的有效方法是什么? 编辑: 预期产出

  • 问题内容: T-SQL DateTime问题。 我有一组时间范围。在这些时间范围内,可能会有一组重叠的时间范围,我称之为“封锁”时间。封锁的时间不会超过一天。我想要做的是分配时间以排除阻塞时间,基本上是给我没有“阻塞”的时间范围。可以肯定的是,阻塞时间不能超出时间范围。 示例:我工作时间是从上午9点到下午5点,在下午1点有30分钟的午餐时间。我想要2行的结果:9am至1pm和1.30pm至5pm。

  • 问题内容: 该表用于存储会话(事件): 我们不想在范围之间产生冲突。 假设我们需要在 2010-01-05 至 2010-01-25之间 插入一个新会话。 我们想知道有冲突的会话。 这是我的查询: 结果如下: 有没有更好的方法来做到这一点? 小提琴 问题答案: 我曾经用日历应用程序进行过这样的查询。我想我使用了这样的东西: 更新 这肯定应该工作((ns,ne,es,ee)=(new_start,n

  • 我创建了一个事件。现在我想检查它们是否重叠。我在数据库中以日期格式存储了开始时间和结束时间。 现在我想检查事件的时间是否重叠。为此,我想获取所有事件start Time和endTime,从日期检索小时和分钟,然后将小时和分钟与当前小时和分钟进行比较。 日期格式如下:df=新的SimpleDateFormat(“E-MMM-dd-HH:mm:ss-zz-yyyy”); 我第一次尝试通过查询比较两个日

  • 问题内容: 我有一个具有以下结构的表:ID,Month,Year,Value,每个ID每个月一个条目的值,大多数月份都具有相同的值。 我想为该表创建一个视图,该视图折叠如下所示的相同值:ID,开始月,结束月,开始年,结束年,值,每个值每个ID一行。 要注意的是,如果值发生变化然后又回到原始值,则表中应该有两行 所以: 100 1 2008 80 100 2 2008 80 100 3 2008 9

  • 问题内容: 我有一个包含以下字段的MySQL表: 名称 开始时间 时间结束 并且是MySQL 字段(不是)。我需要一种定期“扫描”表以查看表中时间范围是否重叠的方法。如果有来自和的其他事件,我想提醒您时间重叠。 真的没什么好想的,我只想知道是否存在重叠。 我将使用PHP执行此操作。 问题答案: 这是我很多年前找到答案的查询模式: 要找到“任何重叠”,您可以将时间范围的 相对 两端彼此进行比较。我必