以this question为基础:
如果events
表包含带有多个值的“会议室”列,并且您想按房间参加重叠的会议,接受的答案将如何变化?该表可能如下所示:
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;
答案 0 :(得分:1)
第一个cte cte_e对数据进行排序。第二个cte_group获取重叠组的数量。第三个cte_range是递归的,用于获取重叠组的最大结束时间。最后一个CTE仅获取每个重叠组中的所有记录,并获取最大created_at时间。
;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;
答案 1 :(得分:1)
加入条件:
如果找不到其他行,则表示您是一个人,要么是因为没有重叠,要么是您是最近的日期。
SELECT a.*
FROM "events" a
LEFT JOIN "events" b
ON a.room = b.room
AND a.id <> b.id
AND a."start" <= b."end"
AND a."end" >= b."start"
AND a.created_at < b.created_at
WHERE b.id IS NULL;
输出
| 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 |