我有一张如下所示的表格:
CREATE TABLE time_records (
id uuid NOT NULL,
employee_id uuid NOT NULL,
starttime timestampt NOT NULL,
endtime timestampt NOT NULL
)
同一个employee_id的记录之间会有时间重叠:
id | 员工_id | 开始时间 | 结束时间 |
---|---|---|---|
1 | 1 | '2023-09-01 07:00:00' | '2023-09-01 09:15:00' |
2 | 1 | '2023-09-01 07:00:00' | '2023-09-01 15:00:00' |
3 | 1 | '2023-09-01 07:00:00' | '2023-09-01 15:00:00' |
4 | 1 | '2023-09-01 14:00:00' | '2023-09-01 15:00:00' |
5 | 1 | '2023-09-01 23:45:00' | '2023-09-01 23:59:00' |
6 | 1 | '2023-09-01 23:45:00' | '2023-09-01 23:59:00' |
我想做的是获取所有这些时间范围内的时间范围:
员工_id | 开始时间 | 结束时间 | id |
---|---|---|---|
1 | '2023-09-01 07:00:00' | '2023-09-01 15:00:00' | [1,2,3,4] |
1 | '2023-09-01 23:45:00' | '2023-09-01 23:29:00' | [5,6] |
如果一天内只有一组重叠时间,使用最大/分钟作为开始和结束时间,我可以让它工作,但当一天中有多组重叠时间时,我似乎无法让它工作:
select timea.employee_id,
min(timea.starttime) starttime,
max(timea.endtime) endtime,
array_agg(timea.id) ids
from time_records timea
inner join time_records timea2 on timea.employee_id = timea2.employee_id and
tsrange(timea2.starttime, timea2.endtime, '[]') &&
tsrange(timea.starttime, timea.endtime, '[]')
and timea.id != timea2.id
group by timea.employee_id;
结果:
员工_id | 开始时间 | 结束时间 | id |
---|---|---|---|
1 | '2023-09-01 07:00:00' | '2023-09-01 23:59:00' | [1,2,3,4,5,6] |
使用
cte
:
with cte as (
select t.employee_id, t.starttime, max(t.endtime) m from time_records t
group by t.employee_id, t.starttime
)
select c.employee_id, c.starttime, c.m, jsonb_agg(t.id)
from cte c join time_records t on c.starttime <= t.starttime and t.endtime <= c.m
where not exists (select 1 from cte t1 where t1.employee_id = c.employee_id and t1.starttime < c.starttime and c.m <= t1.m)
group by c.employee_id, c.starttime, c.m