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

如何确保条目具有不重叠的时间范围?

百里君博
2023-03-14
问题内容

我需要确保数据库仅包含两个或两个以上列是唯一的条目。这可以很容易地通过UNIQUE对那些列的约束来实现。

就我而言,我只需要在重叠的时间范围内禁止重复。该表具有valid_fromvalid_to列。在某些情况下,可能首先需要通过设置来使活动条目到期valid_to = now,然后插入调整为valid_from = now和的新条目valid_to = infinity

使用似乎可以使先前的条目到期而没有任何问题UPDATE,但是由于我的基本列当前为UNIQUE,因此插入新条目似乎很麻烦,因此无法再次添加。

我考虑添加valid_fromvalid_to作为UNIQUE约束的一部分,但这只会使约束更加宽松,并允许重复 重叠的时间范围存在。

如何约束以确保不存在重叠的valid_from和重复项valid_to tsrange

我似乎在寻找EXCLUDE USING GIST,但它似乎不支持多列?这似乎不适用于我:

ALTER TABLE registration 
DROP Constraint IF EXISTS registration_{string.Join('_', listOfAttributes)}_key, 
ADD Constraint registration_{string.Join('_', listOfAttributes)}_key EXCLUDE USING GIST({string.Join(',', listOfAttributes)} WITH =, valid WITH &&);

问题答案:

您走在正确的轨道上。但是排除约束的语法略有不同。

根据未公开的表定义,您可能需要首先安装扩展(附加模块)btree_gist。每个db一次。在我的示例中是必需的,integer因为默认情况下未为类型安装必需的运算符类:

CREATE EXTENSION btree_gist;

看:

  • PostgreSQL排除使用错误:数据类型整数没有默认的运算符类
  • 如何在PostgreSQL中使用(安装)dblink?

然后:

CREATE TABLE registration  (
  tbl_id integer PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY
, col_a  integer NOT NULL
, col_b  integer NOT NULL
, valid_from timestamp
, valid_to   timestamp
, CONSTRAINT no_overlap
    EXCLUDE USING gist ( **col_a with =, col_b with =, tsrange(valid_from, valid_to) WITH &&**)
);

每列都需要使用其各自的运算符列出。

并且您需要一个 范围类型
。您提到了单独的列valid_fromvalid_to。您还会在失败的命令中提及tsrangevalid。令人困惑。假设有两timestamp列,则带有该表达式的表达式索引tsrange(valid_from, valid_to)可以做到这一点。

也许,更好的设计将是您的registration表与新registration_range表中的1-N条目之间的一对多关系。和一些逻辑来确定当前有效的条目(对于任何给定的时间点)。取决于更多未公开的信息。



 类似资料:
  • 问题内容: 我有一个按名称列出的客户表:在SQL中,其中有3列:, 此表中有重复的条目,但 时间戳记 不同。 例如 我想从数据库中消除此问题,并保持第一时间/日期可用。 谢谢。 问题答案: 这有效,请尝试: 在子查询中,它确定哪个记录是每个的第一个记录,然后删除所有其他记录以作重复。我还添加了该子句,该子句返回受该语句影响的行。 您也可以通过使用排名功能来做到这一点: 看看哪一个查询开销较小并使用

  • 问题内容: 我有一个元组列表,每个元组都是一个。我正在尝试合并所有重叠的时间范围,并返回不同时间范围的列表。例如 这是我的实现方法。 我想弄清楚是否 是某些python模块中的内置函数可以更有效地做到这一点吗?要么 有没有达到相同目标的更Python方式? 感谢您的帮助。谢谢! 问题答案: 使用Pythonic可以提高效率的几种方法: 消除了构造,因为该算法应在主循环中删除重复项。 如果只需要遍历

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

  • 问题内容: 假设您有一个包含标识符,开始时间和结束时间的表。这些开始和结束时间可以是任何时间长度。开始时间总是早于结束时间。假设没有空值。 哪种查询会告诉我最“受欢迎”的时间,即每行中的两个范围与其他大多数行重叠的地方? 现实生活中的应用是,它是一个记录用户登录和注销时间的表格。我想编写一个查询,该查询将告诉我何时有最多并发用户登录,并查看这段时间。 谢谢你。 问题答案: 这是使用简单自连接和a的

  • 问题内容: 我在PostgreSQL 9.2中有一张表,看起来像这样(简化): 对于每个feature_id,可能会有多行,其时间范围由begin_time / end_time指定。它们可能重叠,但这是相对罕见的。我正在寻找一种快速的方法来查找所有具有/不具有 任何 重叠的feature_id 。 我尝试使用窗口函数来执行此操作,如下所示: …但这是行不通的: 该算法很简单:按begin_tim

  • 问题内容: 我有一个Java程序,每20秒从Spring Qquartz执行一次。有时只需几秒钟即可执行,但是随着数据变大,我确信它会运行20秒或更长时间。 在一个实例仍在执行时,如何防止Quartz触发/触发作业?发射2个在数据库上执行相同操作的作业效果不佳。有没有办法可以进行某种同步? 问题答案: 如果您需要做的是每20秒发射一次,则Quartz严重过度使用。对于这项工作,应该足够了。 的还提