Sql 跨多个值移除具有开始和结束时间戳的部分/完全重叠事件
基于: 如果events表包含一个具有多个值的Room列,并且您希望按Room删除重叠的会议,那么接受的答案将如何更改?该表可能看起来像:Sql 跨多个值移除具有开始和结束时间戳的部分/完全重叠事件,sql,postgresql,Sql,Postgresql,基于: 如果events表包含一个具有多个值的Room列,并且您希望按Room删除重叠的会议,那么接受的答案将如何更改?该表可能看起来像: id start end created_at room 1 2019-01-23 18:30:00.0 2019-01-23 19:00:00.0 2019-01-18 21:28:27.427612 Room1 2 20
id start end created_at room
1 2019-01-23 18:30:00.0 2019-01-23 19:00:00.0 2019-01-18 21:28:27.427612 Room1
2 2019-01-23 18:30:00.0 2019-01-23 19:00:00.0 2019-01-23 01:04:05.861876 Room1
3 2019-01-23 18:00:00.0 2019-01-23 18:45:00.0 2019-01-16 17:14:50.709552 Room1
4 2019-01-23 18:30:00.0 2019-01-23 19:30:00.0 2019-01-22 19:24:05.532491 Room1
5 2019-01-23 18:30:00.0 2019-01-23 19:30:00.0 2019-01-18 17:28:40.074205 Room1
6 2019-01-23 20:00:00.0 2019-01-23 20:30:00.0 2019-01-18 15:22:30.736888 Room1
7 2019-01-23 20:15:00.0 2019-01-23 20:45:00.0 2019-01-20 20:20:20.202020 Room1
8 2019-01-23 18:30:00.0 2019-01-23 19:00:00.0 2019-01-18 21:28:27.427612 Room2
9 2019-01-23 18:30:00.0 2019-01-23 19:00:00.0 2019-01-23 01:04:05.861877 Room2
10 2019-01-23 18:00:00.0 2019-01-23 18:45:00.0 2019-01-16 17:14:50.709552 Room2
11 2019-01-23 18:30:00.0 2019-01-23 19:30:00.0 2019-01-22 19:24:05.532491 Room2
12 2019-01-23 18:30:00.0 2019-01-23 19:30:00.0 2019-01-18 17:28:40.074205 Room2
13 2019-01-23 20:00:00.0 2019-01-23 20:30:00.0 2019-01-18 15:22:30.736888 Room2
14 2019-01-23 20:15:00.0 2019-01-23 20:45:00.0 2019-01-20 20:20:20.202020 Room2
15 2019-01-23 20:00:00.0 2019-01-23 20:30:00.0 2019-01-18 15:22:30.736888 Room3
16 2019-01-23 20:15:00.0 2019-01-23 20:45:00.0 2019-01-20 20:20:20.202021 Room3
最终结果是:
id start end created_at room
2 2019-01-23 18:30:00.0 2019-01-23 19:00:00.0 2019-01-23 01:04:05.861876 Room1
7 2019-01-23 20:15:00.0 2019-01-23 20:45:00.0 2019-01-20 20:20:20.202020 Room1
9 2019-01-23 18:30:00.0 2019-01-23 19:00:00.0 2019-01-23 01:04:05.861877 Room2
14 2019-01-23 20:15:00.0 2019-01-23 20:45:00.0 2019-01-20 20:20:20.202020 Room2
16 2019-01-23 20:15:00.0 2019-01-23 20:45:00.0 2019-01-20 20:20:20.202021 Room3
下面上一个问题的答案只能给出时间段中所有房间的最新创建事件,而不是房间
select max(id), min(start), max(end), max(created_at)
from (select t.*,
count(*) filter (where max_end < end) over (order by start) as grouping
from (select t.*,
max(end) over (order by start rows between unbounded preceding and 1 preceding) as max_end
from events t
) t
) t
group by grouping;
第一个cte cte对数据进行排序。第二个cte_组获取重叠组的数量。第三个cte_范围是递归的,用于获得重叠组的最大结束时间。最后一个cte只需获取每个重叠组中的所有记录,并获取当时创建的最大值
;WITH RECURSIVE cte_e
AS
(
SELECT *, row_number() OVER (PARTITION BY room ORDER BY start,"end") AS row_id
FROM events
),
cte_group
AS
(
SELECT c.id,c."start",c."end",c.room,c.row_id,n."end" AS next_end
FROM cte_e c
LEFT JOIN cte_e n
ON c.room=n.room
AND c.row_id=n.row_id-1
LEFT JOIN cte_e p
ON p.room=c.room
AND p.row_id=c.row_id-1
WHERE (p."end" IS NULL OR p."end"<c."start")
AND c."end" > n."start"
),
cte_range
AS
(
SELECT *
FROM cte_group
UNION ALL
SELECT c.id,c."start",c."end",c.room,c.row_id,e."end" AS next_end
FROM cte_group c
LEFT JOIN cte_e e
ON c.room=e.room
AND c.row_id<e.row_id
AND c."end">e."start"
WHERE e."end" IS NOT NULL
),
cte_max AS
(
SELECT g.room,MAX(e.created_at) AS created_at
FROM cte_range g
INNER JOIN events e
ON g.room=e.room
AND g."start"<e."end"
AND g."end">e."start"
GROUP BY g.room,g.row_id
)
SELECT e.*
FROM events e
INNER JOIN cte_max m
ON e.room=m.room
AND e.created_at=m.created_at;
第一个cte cte对数据进行排序。第二个cte_组获取重叠组的数量。第三个cte_范围是递归的,用于获得重叠组的最大结束时间。最后一个cte只需获取每个重叠组中的所有记录,并获取当时创建的最大值
;WITH RECURSIVE cte_e
AS
(
SELECT *, row_number() OVER (PARTITION BY room ORDER BY start,"end") AS row_id
FROM events
),
cte_group
AS
(
SELECT c.id,c."start",c."end",c.room,c.row_id,n."end" AS next_end
FROM cte_e c
LEFT JOIN cte_e n
ON c.room=n.room
AND c.row_id=n.row_id-1
LEFT JOIN cte_e p
ON p.room=c.room
AND p.row_id=c.row_id-1
WHERE (p."end" IS NULL OR p."end"<c."start")
AND c."end" > n."start"
),
cte_range
AS
(
SELECT *
FROM cte_group
UNION ALL
SELECT c.id,c."start",c."end",c.room,c.row_id,e."end" AS next_end
FROM cte_group c
LEFT JOIN cte_e e
ON c.room=e.room
AND c.row_id<e.row_id
AND c."end">e."start"
WHERE e."end" IS NOT NULL
),
cte_max AS
(
SELECT g.room,MAX(e.created_at) AS created_at
FROM cte_range g
INNER JOIN events e
ON g.room=e.room
AND g."start"<e."end"
AND g."end">e."start"
GROUP BY g.room,g.row_id
)
SELECT e.*
FROM events e
INNER JOIN cte_max m
ON e.room=m.room
AND e.created_at=m.created_at;
连接条件:
尝试在同一房间内找到其他活动
但你需要有一个不同的身份证
日期必须重叠
最后必须有一个更晚的创建日期。
如果你找不到任何其他行,意味着你是孤独的,要么因为没有重叠,要么因为你是最新的日期
连接条件:
尝试在同一房间内找到其他活动
但你需要有一个不同的身份证
日期必须重叠
最后必须有一个更晚的创建日期。
如果你找不到任何其他行,意味着你是孤独的,要么因为没有重叠,要么因为你是最新的日期
你能解释一下欲望输出的逻辑吗?因为我看到room1的19:30被忽略了。@JuanCarlosOropeza,以及'2019-01-23 18:00:00.0`@JuanCarlosOropeza,逻辑是:将所有重叠的事件组合在一起,并显示最新创建的事件。在房间1的时间段18:00-19:30之间有5个事件重叠。在这五个事件中,最新创建的时间为18:30-19:00。你能解释一下欲望输出的逻辑吗?因为我看到room1的19:30被忽略了。@JuanCarlosOropeza,以及'2019-01-23 18:00:00.0`@JuanCarlosOropeza,逻辑是:将所有重叠的事件组合在一起,并显示最新创建的事件。在房间1的时间段18:00-19:30之间有5个事件重叠。在这五项活动中,最新创建时间为18:30-19:00的活动。www.sqlfiddle.com/!17/75d02/1/0-我得到一个空输出,因此每个房间都有多个重叠集,并且您希望获得每个房间每个重叠组的最后一条记录。www.sqlfiddle.com/!17/75d02/1/0-我得到一个空输出,因此每个房间都有多个重叠集,并且您希望获得每个房间每个重叠组的最后一条记录。
| id | start | end | created_at | room |
|----|----------------------|----------------------|-----------------------------|-------|
| 2 | 2019-01-23T18:30:00Z | 2019-01-23T19:00:00Z | 2019-01-23T01:04:05.861876Z | Room1 |
| 7 | 2019-01-23T20:15:00Z | 2019-01-23T20:45:00Z | 2019-01-20T20:20:20.20202Z | Room1 |
| 9 | 2019-01-23T18:30:00Z | 2019-01-23T19:00:00Z | 2019-01-23T01:04:05.861877Z | Room2 |
| 14 | 2019-01-23T20:15:00Z | 2019-01-23T20:45:00Z | 2019-01-20T20:20:20.20202Z | Room2 |
| 16 | 2019-01-23T20:15:00Z | 2019-01-23T20:45:00Z | 2019-01-20T20:20:20.202021Z | Room3 |