确定最大重叠日期时间范围数

raogr8fs  于 2021-06-17  发布在  Mysql
关注(0)|答案(2)|浏览(492)

我有一张table DATETIME 范围,比如

  1. id | start | end
  2. ----------------------------------------------
  3. 1 | 2011-12-18 16:00:00 | 2011-12-18 17:00:00
  4. 2 | 2011-12-19 08:00:00 | 2011-12-19 10:00:00
  5. 3 | 2011-12-19 11:00:00 | 2011-12-19 13:00:00
  6. 4 | 2011-12-19 12:00:00 | 2011-12-19 14:00:00
  7. 5 | 2011-12-19 13:00:00 | 2011-12-19 15:00:00
  8. 6 | 2011-12-19 13:00:00 | 2011-12-19 14:00:00
  9. 7 | 2011-12-20 13:00:00 | 2011-12-20 14:00:00

因此,2011-12-19日的范围如下:

  1. 8 9 10 11 12 13 14 15
  2. <-------->
  3. <-------->
  4. <-------->
  5. <-------->
  6. <---->

目标是,在插入新记录时,找到已经存在的最大重叠范围数:即:插入新范围时 2011-12-19 12:00:00 - 2011-12-19 15:00:00 我想收到 3 ,因为重叠范围的最大数目是3,从13:00到14:00。
从现在起我就有了这个

  1. select
  2. count(*) as cnt
  3. from
  4. mytable as p
  5. where
  6. ( # check if new renge overlap existings ones
  7. (@start >= start and @start < end)
  8. or
  9. (@end > start and @end <= end)
  10. )
  11. or
  12. ( # check if existing range is included by new one
  13. start between @start and @end
  14. and
  15. end between @start and @end
  16. )

但这次回归 4 因为它检测除第一个范围以外的所有范围,但是是错误的。
我已经找到了
确定两个日期范围是否重叠
如何在sql中选择重叠的日期范围
检查表是否有时间重叠?
但所有这些问题都略有不同。
我使用的是MySQL5.7,但是如果需要的话可以升级到8。

ibrsph3r

ibrsph3r1#

考虑到起点和终点永远不会相同:

  1. select
  2. count(*) as cnt
  3. from
  4. mytable as p
  5. where
  6. # check if new renge overlap existings ones
  7. (@start < end and @end > start);
bnlyeluc

bnlyeluc2#

这个答案适用于包含窗口函数的mysql 8.0。解决方案的核心将是以下查询,它为数据中每个感兴趣的间隔找到许多重叠的间隔:

  1. select t2.startDt, t2.endDt, count(*) overlaps_count
  2. from
  3. (
  4. select lag(t1.dt) over (order by t1.dt) startDt, t1.dt endDt
  5. from
  6. (
  7. select startt dt from data
  8. union
  9. select endt dt from data
  10. ) t1
  11. ) t2
  12. join data on t2.startDt < data.endt and t2.endDt > data.startt
  13. group by t2.startDt, t2.endDt

dbfiddle演示
一旦有了这个结果(称之为重叠表),就可以很容易地找到输入间隔的最大值,如下所示

  1. with Overlap as
  2. (
  3. -- the query above
  4. )
  5. select max(overlaps_count)
  6. from Overlap
  7. where @start < endDt and @end > startDt
展开查看全部

相关问题