【问题标题】:SQL consecutive occurrences for availability based query基于可用性的查询的 SQL 连续出现
【发布时间】:2016-10-16 17:41:31
【问题描述】:

我在尝试创建一个相当复杂的 SQL,尤其是 MySQL 时有点卡住了。

数据库处理汽车租赁,什么是雪花图案的主表看起来有点像:

  id   | rent_start | rent_duration | rent_end     |  customerID |    carId
  -----------------------------------------------------------------------------------
  203  | 2016-10-03 |       5       |  2016-11-07  |    16545    |    4543
  125  | 2016-10-20 |       9       |  2016-10-28  |    54452    |    5465  
  405  | 2016-11-01 |       2       |  2016-01-02  |    43565    |    346

我的目标是创建一个允许给定的查询

1) 一个周期范围,例如:从 2016-10-03 到 2016-11-03 2) 天数,例如:10

允许我检索在 10 月 10 日至 11 日之间至少连续 10 天实际可用的汽车。 这些汽车的 ID 列表绰绰有余……我只是不知道如何设置这样的查询。

如果有帮助:我确实在另一个表中有所有汽车 ID 的列表。

无论如何,谢谢!

【问题讨论】:

    标签: mysql sql find-occurrences availability


    【解决方案1】:

    我认为为此目的,使用可用性而不是租金要简单得多。

    所以:

    select r.car_id, r.rent_end as avail_start,
           (select min(r2.rent_start
            from rentals r2
            where r2.car_id = r.car_id and r2.rent_start > r.rent_start
           ) as avail_end
    from rentals r;
    

    那么,对于您的查询,您至少需要 10 天。为此,您可以使用 having 子句或子查询:

    select r.*
    from (select r.car_id, r.rent_end as avail_start,
                 (select min(r2.rent_start
                  from rentals r2
                  where r2.car_id = r.car_id and r2.rent_start > r.rent_start
                 ) as avail_end
          from rentals r
         ) r
    where datediff(avail_end, avail_start) >= $days;
    

    最后,您需要将该时间段设置为您指定的日期:

    select r.*
    from (select r.car_id, r.rent_end as avail_start,
                 (select min(r2.rent_start
                  from rentals r2
                  where r2.car_id = r.car_id and r2.rent_start > r.rent_start
                 ) as avail_end
          from rentals r
         ) r
    where datediff(avail_end, avail_start) >= $days and
          ( (avail_end > $end and avail_start < $start) or
            (avail_start <= $start and avail_end >= $start + interval 10 day) or
            (avail_start > $start and avail_start + interval 10 day <= $end)
          );
    

    这可以处理免费时段覆盖整个范围或在该范围内开始/结束的各种情况。

    毫无疑问,在这个逻辑中存在一个错误(汽车是否在返回的同一天可用)。这应该为您提供解决问题的可靠方法。

    顺便说一句,您还应该包括从未租过的汽车。但这对于您在问题中描述的表格是不可能的。

    【讨论】:

    • 工作得非常好,是的,你提到的问题(没有预订的房间)实际上是一个。
    • 还有一个是将第一个可用日期计算为第一个租用的结束日期。这意味着,如果一辆车只租过一次,或者预订只租一次,则之前的任何日期都将被视为不可用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 1970-01-01
    相关资源
    最近更新 更多