繁体   English   中英

MySQL中的连续日期可用性查询?

[英]Continous date availability query in MySQL?

我的数据库中有一个表,其中包含以下数据:

————————————————————————————————————————————————————————————————————————
Id          startDate          availabilityStatus        Hotel_Id
————————————————————————————————————————————————————————————————————————
1          2016-07-01             available                 2
2          2016-07-02             available                 2
3          2016-07-03             unavailable               2
4          2016-07-04             available                 3
5          2016-07-05             available                 3
6          2016-07-06             available                 3
7          2016-07-07             unavailable               4
8          2016-07-08             available                 4
9          2016-07-09             available                 4
10         2016-07-10             available                 4

现在,用户希望看到所有在2016年7月连续3天可用的酒店

我可以进行查询以获取可用性,但不确定如何获取连续日期可用性。

根据上述数据,7月份只有Hotel Id 3, 4有连续可用的日期,但是2也有日期。 那么我们应该如何删除2并通过MySQL查询显示3, 4

请指教?

您可以使用以下查询:

SELECT DISTINCT t1.hotel_id
FROM mytable AS t1
JOIN mytable AS t2 
   ON t1.hotel_id = t2.hotel_id AND 
      DATEDIFF(t1.startDate, t2.startDate) = 2 AND
      t1.availabilityStatus = 'available' AND
      t2.availabilityStatus = 'available'
LEFT JOIN mytable AS t3 
   ON t1.hotel_id = t3.hotel_id AND 
      t3.startDate < t2.startDate AND t3.startDate > t1.startDate AND 
      t3.availabilityStatus = 'unavailable'  
WHERE t3.hotel_id IS NULL   

查询以这种方式编写,因此可以轻松调整以适应更长的可用期。

编辑:

这是使用变量的解决方案:

SELECT DISTINCT hotel_id
FROM (
  SELECT hotel_id,
         @seq := IF(@hid = hotel_id, 
                    IF(availabilityStatus = 'available', @seq + 1, 0),
                    IF(@hid := hotel_id, 
                       IF(availabilityStatus = 'available', 1, 0),
                       IF(availabilityStatus = 'available', 1, 0))) AS seq
  FROM mytable
  CROSS JOIN (SELECT @seq := 0, @hid := 0) AS vars
  ORDER BY hotel_id, startDate) AS t
WHERE t.seq >= 3  

您可以使用实际数据集对其进行测试,并告诉我们它与第一个解决方案的对比情况。

尝试类似的东西。 它适用于任何天数。 3替换N

SELECT DISTINCT A.Hotel_Id FROM table A
WHERE 
   A.availabilityStatus = 'available' AND
   N-1 = (
      SELECT count(DISTINCT startDate) FROM table B
      WHERE B.availabilityStatus = 'available' 
        AND A.Hotel_Id = B.Hotel_Id
        AND B.startDate 
              BETWEEN DATE_ADD(A.startDate, INTERVAL 1 DAY) 
                  AND DATE_ADD(A.startDate, INTERVAL N-1 DAY) 
   )

它的工作原理如下:对于每个可用日期,计算下一天N-1的可用日期。 如果他们的计数是N-1,请将hotel_id添加到结果中。

试试这个。 我没有机会测试它,因为sqlfiddle不工作,但一般的想法是分别通过在start date添加12天来再增加2个表的实例。

然后根据派生日期和酒店ID加入他们。

select t1.hotelid from
 (select * from Table1 where availabilityStatus='available' ) t1
inner join 
 (select a.*, DATE_ADD(startDate,INTERVAL 1 DAY) as date_plus_one 
    from Table1 where availabilityStatus='available' ) t2
on t1.start_date=t2.date_plus_one and t1.hotelid=t2.hotelid
 inner join 
(select a.*, DATE_ADD(startDate,INTERVAL 2 DAY) as date_plus_two
    from Table1 where availabilityStatus='available' ) t3
on t1.start_date=t3.date_plus_two and t1.hotelid=t3.hotelid

此查询使用双重自联接来查找在第a,b和c天可用的相同酒店,按天分配(函数ADDDATE)。

SELECT DISTINCT a.Hotel_Id
FROM table a
INNER JOIN table b ON a.Hotel_Id=b.Hotel_Id
INNER JOIN table c ON a.Hotel_Id=c.Hotel_Id
WHERE ADDDATE(a.startDate , INTERVAL 1 DAY) = b.startDate
  AND ADDDATE(a.startDate , INTERVAL 2 DAY) = c.startDate
  AND a.availabilityStatus = 'available'
  AND b.availabilityStatus = 'available'
  AND c.availabilityStatus = 'available'

它的工作正常......

SELECT a.hotel_id FROM `mytable` as a WHERE 
    (select COUNT(id) from mytable as a1 where 
        DATE(a1.startDate)=DATE_ADD(a.startDate,INTERVAL 1 DAY)  and        
        a1.hotel_id=a.hotel_id and 
        a1.availabilityStatus="Available"
    ) >0

    and

    (select COUNT(id) from mytable as a1 where 
        DATE(a1.startDate)=DATE_ADD(a.startDate,INTERVAL -1 DAY) and 
        a1.hotel_id=a.hotel_id and 
        a1.availabilityStatus="Available"
    ) >0

    and

    (select COUNT(id) from mytable as a1 where 
        DATE(a1.startDate)=DATE(a1.startDate) and
        a1.hotel_id=a.hotel_id and 
        a1.availabilityStatus="Available"
    ) >0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM