简体   繁体   English

PostgreSQL,查找并修复重叠的时间段

[英]PostgreSQL, finding and fixing overlapping time periods

I have time periods spent in different units per user in a table. 我在表中每个用户使用不同单位的时间段。 The time periods overlap and I would like to fix that. 时间段重叠,我想解决这个问题。 I have: 我有:

user|unit|start_time|end_time
   1|   1|2015-01-01|2015-01-31
   1|   2|2015-01-07|2015-01-14
   2|   1|2015-01-09|2015-01-13
   2|   2|2015-01-10|2015-01-15

ie. 即。 user 1 started at unit 1 on 2015-01-01, transfered to unit 2 on 2015-01-07, returned to unit 1 on 2015-01-14 and left unit 1 on the 2015-01-31. 用户1在2015-01-01的单元1开始,在2015-01-07转移到单元2,在2015-01-14返回到单元1,并在2015-01-31离开了单元1。 The user can't be in two places at once so the table should look more like this: 用户不能一次处于两个位置,因此该表应如下所示:

user|unit|start_time|end_time
   1|   1|2015-01-01|2015-01-07 --fixed end_time
   1|   2|2015-01-07|2015-01-14
   1|   1|2015-01-14|2015-01-31 --newly created line
   2|   1|2015-01-09|2015-01-10 --fixed end_time
   2|   2|2015-01-10|2015-01-15

Here is some SQL to create the test table with some entries. 这是一些使用一些条目创建测试表的SQL。

CREATE TABLE users_n_units
(
users character varying (100),
units character varying (100),
start_time date,
end_time date
);

INSERT INTO users_n_units (users,units,start_time,end_time) 
VALUES ('1','1','2015-01-01','2015-01-31'),
       ('1','2','2015-01-07','2015-01-14'),
       ('2','1','2015-01-09','2015-01-13'),
       ('2','2','2015-01-10','2015-01-15');

You don't really give enough information to fully answer this, and as others have pointed out you may end up with special cases so you should analyze what your data looks like carefully before running updates. 您实际上没有提供足够的信息来完全回答这个问题,并且正如其他人指出的那样,您可能会遇到特殊情况,因此在运行更新之前,应仔细分析数据的外观。

But in your test environment you can try something like this. 但是在测试环境中,您可以尝试这样的操作。 The trick is to join your table to itself with clauses that restricts you to the data that matches your business logic properly, and then update it. 诀窍是使用一些子句将表连接到自身,这些子句将您限制在与业务逻辑正确匹配的数据上,然后对其进行更新。

This statement works on your tiny sample set and just runs through and mechanically sets end times to the following time period's start times. 该语句适用于您的小型样本集,只是贯穿整个过程并以机械方式将结束时间设置为以下时间段的开始时间。 I have used something very similar to this on similar problems before so I know the mechanism should work for you. 之前,我在类似问题上使用了与之非常相似的东西,所以我知道该机制应该对您有用。

CAUTION: not tested on anything other than this small set. 小心:除此小型装置外,未经测试。 Don't run on production data! 不要运行生产数据!

UPDATE a SET a.end_time = b.start_time 
FROM users_n_units a 
INNER JOIN users_n_units b ON a.users = b.users AND a.units < b.units

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM