Postgres 查询从时间范围列表中查找唯一时间段

问题描述 投票:0回答:1

我有一张如下所示的表格:

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]
sql postgresql postgresql-9.6
1个回答
0
投票

使用

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

看小提琴

© www.soinside.com 2019 - 2024. All rights reserved.