删除具有多个值的开始和结束时间戳记的部分/完全重叠的事件

时间:2019-07-16 18:59:23

标签: sql postgresql

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;

2 个答案:

答案 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)

加入条件:

如果找不到其他行,则表示您是一个人,要么是因为没有重叠,要么是您是最近的日期。

SQL DEMO

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 |