我有一张表,event,有一个timestamptzunique_time列.我需要unique_time中的每个值都是唯一的.

给定一个timestamptz输入input_time,我需要找到满足以下条件的minimum timestamptz值:

  • 结果必须是>=input_time
  • 结果一定不是unique_time

我不能只给unique_time中的最大值加1微秒,因为我需要满足上述条件的最小值.

是否有一种简洁的方法可以将其作为event表的插入或更新的一部分进行计算?

推荐答案

我建议使用带有循环的函数:

CREATE OR REPLACE FUNCTION f_next_free(_input_time timestamptz, OUT _next_free timestamptz)
  LANGUAGE plpgsql STABLE STRICT AS
$func$
BEGIN
   LOOP
      SELECT INTO _next_free  _input_time
      WHERE  NOT EXISTS (SELECT FROM event WHERE unique_time = _input_time);
      
      EXIT WHEN FOUND;
      _input_time := _input_time + interval '1 us';
   END LOOP;
END
$func$;

电话:

SELECT f_next_free('2022-05-17 03:44:22.771741+02');

一定要有一个event(unique_time)的索引.隐式定义的是索引,如果有,则为UNIQUE.

相关的:

由于Postgres时间戳的分辨率为微秒,因此下一个空闲时间戳的距离至少为1微秒(interval '1 us').见:

也可能是递归CTE,但开销可能更大.

并发!

有没有一种简洁的方法可以将其作为INSERTUPDATEevent表的一部分进行计算?

上述情况显然受制于比赛条件.任何数量的并发事务都可能找到相同的空闲位置.Postgres无法锁定尚未存在的行.

既然你想要INSERT(与UPDATE类似),我建议直接在循环中使用INSERT .. ON CONFLICT DO NOTHING.同样,我们需要UNIQUEPRIMARY KEYunique_time:

CREATE OR REPLACE FUNCTION f_next_free(INOUT _input_time timestamptz, _payload text)
  LANGUAGE plpgsql AS
$func$
BEGIN
   LOOP
      INSERT INTO event (unique_time, payload)
      VALUES (_input_time, _payload)
      ON CONFLICT (unique_time) DO NOTHING;
      
      EXIT WHEN FOUND;
      _input_time := _input_time + interval '1 us';
   END LOOP;
END
$func$;

相应地调整"有效载荷".

A successful INSERT locks the row. Even if concurrent transactions cannot see the inserted row yet, a UNIQUE index is absolute.
(You could make it work with advisory locks ...)

Sql相关问答推荐

SQL JOIN of 2 Table with 2 sum

Stack Exchange站点上的最短帖子(按正文长度计算,用户名为原始发帖(SEDE))

为什么Prisma生成唯一索引,而不是基于方案上的唯一列约束?

Oracle SQL-将结果列在单行中

使用占位符向SQL INSERT查询添加 case

正在编写查询.我需要将订阅的时间段分为第一个订阅中包含的另一个订阅之前和之后的时间段

按分类标准检索记录

数组列的postgres更新查询

以一致的价值获得独特的价值

列(值不为空)到其他有序列

复制行并根据 Oracle SQL 中其他表的值更改值

如何在第二个 INSERT 中使用第一个 INSERT 自动生成的 ID

如何从一张表中获取值在至少三行相同的记录

带聚合函数的 percentile_cont

根据行号将列转置为没有任何id或键列的行

如何在 DAX 中通过 Window 函数应用订单

Postgres:表的累积视图

查找具有相同连接列数据的所有记录

我现在如何显示重复的汽车? postgresql

有条件求和