如何避免在PostgreSQL中发现重叠时间戳时插入
我想检查根据客户的时间戳call_start和call_end是否不相同,以便没有客户同时接听两个电话 我在这里插入了一些客户id如何避免在PostgreSQL中发现重叠时间戳时插入,postgresql,Postgresql,我想检查根据客户的时间戳call_start和call_end是否不相同,以便没有客户同时接听两个电话 我在这里插入了一些客户id for rec in (select t.agent_id, t.call_start, t.call_end, t.aht, t.customer_id from temp_sdg_calls t) loop insert into aa_dev.sdg_calls values(rec.agent_id, rec.call_start, rec.
for rec in (select t.agent_id, t.call_start, t.call_end, t.aht, t.customer_id from temp_sdg_calls t) loop
insert into aa_dev.sdg_calls
values(rec.agent_id, rec.call_start, rec.call_end, rec.aht, (select customer_id from aa_dev.sdg_calls order by random() limit 1));
end loop;
我只想在没有类似时间的客户呼叫时从aa_dev.sdg_呼叫中插入customerid,例如,我不需要下面这样的场景。所以为了避免这种情况,我想在插入时检查它,如果出现这种情况,那么选择另一个customerid并在这里插入它
叫你开始
通话结束
客户识别码
2020-11-16 09:12:40
2020-11-16 09:13:05
2345
2020-11-16 09:12:50
2020-11-16 09:13:10
2345
首先选择最佳数据类型:当您有开始和结束时间戳时,它看起来像一个范围。PostgreSQL确实提供了这种数据类型,时间戳范围,tsrange 每个范围都有一个下限和一个上限,即起点和终点。然后还有包含边界和排除边界,表示为[和]的包含边界和(和)的排除边界 大多数情况下,我使用函数来创建范围,在本例中是函数tsrange():
SELECT tsrange('2021-01-20 10:00', '2021-01-20 11:00', '[)');
结果是:
[2021-01-20 10:00:002021-01-20 11:00:00)
这意味着开始于2021-01-20 10:00:00,结束于2021-01-20 11:00:00,但不包括2021-01-20 11:00:00。所以基本上2021-01-20 11:00:00减去1微秒
使用此数据类型,您还可以选择创建,以避免重叠范围。这是使用btree_gist扩展:
CREATE EXTENSION btree_gist;
CREATE TABLE sdg_calls (
customer_id int4 NOT NULL,
ts_call tsrange NOT NULL,
CONSTRAINT unique_customer_call EXCLUDE USING gist (customer_id public.gist_int4_ops WITH pg_catalog.=, ts_call pg_catalog.range_ops WITH pg_catalog.&&)
)
;
INSERT INTO sdg_calls(customer_id, ts_call) VALUES(1, tsrange('2021-02-01 10:00', '2021-02-01 10:15','[)'));
INSERT INTO sdg_calls(customer_id, ts_call) VALUES(1, tsrange('2021-02-01 10:15', '2021-02-01 10:30','[)'));
下一个将失败:
INSERT INTO sdg_calls(customer_id, ts_call) VALUES(1, tsrange('2021-02-01 10:25', '2021-02-01 10:45','[)'));
现在,您的日常工作中有许多和运算符。这在使用计划软件、预订等时尤其方便。首先选择最佳数据类型:当您有开始和结束时间戳时,它看起来像一个范围。PostgreSQL确实提供了这个数据类型,时间戳范围,tsrange 每个范围都有一个下界和一个上界,即开始和结束。然后还有包含和排除边界,用[和]表示包含边界,用(和)表示排除边界 大多数情况下,我使用函数来创建范围,在本例中是函数tsrange():
SELECT tsrange('2021-01-20 10:00', '2021-01-20 11:00', '[)');
结果是:
[2021-01-20 10:00:002021-01-20 11:00:00)
这意味着开始于2021-01-20 10:00:00,结束于2021-01-20 11:00:00,但不包括2021-01-20 11:00:00。所以基本上2021-01-20 11:00:00减去1微秒
使用此数据类型,您还可以选择创建,以避免重叠范围。这是使用btree_gist扩展:
CREATE EXTENSION btree_gist;
CREATE TABLE sdg_calls (
customer_id int4 NOT NULL,
ts_call tsrange NOT NULL,
CONSTRAINT unique_customer_call EXCLUDE USING gist (customer_id public.gist_int4_ops WITH pg_catalog.=, ts_call pg_catalog.range_ops WITH pg_catalog.&&)
)
;
INSERT INTO sdg_calls(customer_id, ts_call) VALUES(1, tsrange('2021-02-01 10:00', '2021-02-01 10:15','[)'));
INSERT INTO sdg_calls(customer_id, ts_call) VALUES(1, tsrange('2021-02-01 10:15', '2021-02-01 10:30','[)'));
下一个将失败:
INSERT INTO sdg_calls(customer_id, ts_call) VALUES(1, tsrange('2021-02-01 10:25', '2021-02-01 10:45','[)'));
现在,您的日常工作中有许多和操作员。这在使用规划软件、预订等时特别方便。与问题无关,但为什么逐行插入速度慢且效率低?为什么不使用
insert-into-insert-into-aa_-dev.sdg_调用(…)选择…from temp_sdg_calls
?@a_horse_with_no_name因为我想逐行插入,每一行都应该有不同的id。与问题无关,但为什么逐行插入速度慢且效率低?为什么不使用插入插入aa_dev.sdg_调用(…)选择…从临时sdg呼叫中
?@a_horse_和_no_name_因为我想逐行插入,每一行都应该有不同的id。你能给出一个描述性的答案吗?@Chloe:见上文你能给出一个描述性的答案吗?@Chloe:见上文