使用未在 Mysql 中排序的多个日期范围查询给定月份的日期范围间隙

Posted

技术标签:

【中文标题】使用未在 Mysql 中排序的多个日期范围查询给定月份的日期范围间隙【英文标题】:Query for gaps in date ranges for given month with multiple date ranges which are not sorted in Mysql 【发布时间】:2021-05-08 19:27:26 【问题描述】:

我有一个非常棘手的日历间隙项目,我可以使用一些帮助。我希望我已经很好地概述了我的问题,并且非常感谢在解决这个问题方面的任何帮助。

我需要找出多个日期范围之间的日历间隔。我有一个用于租车的 mysql 数据库。我需要一个查询来显示在给定月份内有间隙的所有汽车。我使用的是 mysql 5.7,所以我不能使用递归查询。

这是我的数据库(mysql)中的内容:

表格:

Car   ||  from_date   || to_date
Ford  ||  2021-05-01  || 2021-05-09 (10 day gap)
Ford  ||  2021-05-20  || 2021-05-30 (0 day gap till next)
Ford  ||  2021-06-01  || 2021-06-07 (7 day gap till next)
Ford  ||  2021-06-15  || 2021-06-20 (5 day gap till next)
Ford  ||  2021-06-26  || 2021-06-30 (0 day gap till next)
Chevy ||  2021-04-20  || 2021-04-29 (7 day gap till next)
Chevy ||  2021-05-07  || 2021-05-12 (7 day gap till next)
Chevy ||  2021-05-20  || 2021-05-23 (8 day gap till next)
Chevy ||  2021-06-02  || 2021-06-10 (13 day gap till next)
Tesla ||  2021-04-15  || 2021-04-30 
Tesla ||  2021-05-01  || 2021-05-30 

场景:在上面的表格中,我创建了以下场景: 福特:5 月和 6 月之间完全有差距。 雪佛兰:在月初和月底有重叠的差距 特斯拉:整个六月都开放

警告:在此示例中,这些记录按 from_date 排序,但它们可能不在现实生活中,因此您不能假设它们的顺序。这就是为什么下面引用的“显示差距”示例对我不起作用的原因。

预期/可接受的结果:下表显示了我的预期,但只要知道汽车在给定月份内是否有任何差距,我就可以了。所以,对于 05,我不需要雪佛兰上市 3 次。如果我们可以通过拉动第一次出现来更快地构建它。只显示每辆车的第一场比赛就可以了。

正确结果:月 = 05,差距 = 7

+------------+------------+------------+------+
|    Car     |  gap_start |  gap_end   | gap  |
+------------+------------+------------+------+
|    Ford    | 2021-05-09 | 2021-05-20 |  10  |
|    Chevy   | 2021-04-29 | 2014-05-07 |   7  |
|    Chevy   | 2021-05-12 | 2014-05-20 |   7  |
|    Chevy   | 2021-05-23 | 2014-06-02 |   8  |
+------------+------------+------------+------+

可接受的结果:月 = 05,差距 = 7

+------------+------------+
|    Car     |  has_gap   |
+------------+------------+
|    Ford    |     1      |
|    Chevy   |     1      |
+------------+------------+

正确结果:月 = 06,差距 = 5

+------------+------------+------------+------+
|    Car     |  gap_start |  gap_end   | gap  |
+------------+------------+------------+------+
|    Ford    | 2021-06-07 | 2021-06-15 |   7  |
|    Ford    | 2021-06-20 | 2021-06-26 |   5  |
|    Chevy   | 2021-06-10 | 2021-06-31 |  20  |
|    Tesla   | 2021-06-01 | 2021-06-30 |  30  |
+------------+------------+------------+------+

可接受的结果:月 = 06,差距 = 5

+------------+----------+
|    Car     |  has_gap |
+------------+----------+
|    Ford    |     1    |
|    Chevy   |     1    |
|    Tesla   |     1    |
+------------+----------+

注意:我意识到我的数学对特斯拉来说是错误的,因为我不得不伪造日期。只要结果中包含特斯拉,我并不关心如何返回。

下一步:我可能会为每辆车及其预订日期构建一个日历(水平条形显示),所以我想一旦我得到结果,我会遍历它们并提取该给定月份的所有预订来构建那个日历。除非有人知道如何在一个查询中完成所有这些操作并保持快速。

我花了一些时间试图涵盖我提出这个问题的所有基础,并希望我没有犯任何错误。请随时提出问题或进行澄清。并且,提前感谢您的帮助。

类似的问题,但不够接近工作。 Show gaps between dates in MySQL

【问题讨论】:

查看我添加的标签是否有帮助。 【参考方案1】:

基本上,我认为您可以使用not exists 和聚合。要在有间隔的时间段内获得汽车:

select car, min(from_date)
from t
where from_date >= $month_start and from_date < $month_end and
      not exists (select 1
                  from t t2
                  where t2.car = t.car and
                        t2.from_date > t.to_date and
                        t2.from_date < t.to_date + interval $gap day
                 )
group by car;

Here 是一个 dbfiddle。

【讨论】:

我尝试在 JSFiddle 中构建它,但它似乎无法执行。 sqlfiddle.com/#!9/21c80f/7

以上是关于使用未在 Mysql 中排序的多个日期范围查询给定月份的日期范围间隙的主要内容,如果未能解决你的问题,请参考以下文章

我如何查询给定日期范围的mysql并加入两个表?

Mysql - 使用多个连接表查找丢失的日期

帮助形成 mysql 查询以查找给定日期范围的免费(可用)场所/资源

Mysql查询 - 返回两个日期范围相交的日期

用于获取多个日期范围的 mysql 查询

Mysql 将给定日期范围内的每日总计转化为每周总计