我的数据库中有一个表,其中包含以下数据:
————————————————————————————————————————————————————————————————————————
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月份只有酒店身份3, 4
有连续的可用日期,但2
也有可用的日期。那么我们应该如何删除2
并通过MySQL查询显示3, 4
。
请指教?
答案 0 :(得分: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
您可以使用实际数据集对其进行测试,并告诉我们它与第一个解决方案的对比情况。
答案 1 :(得分:1)
尝试类似的东西。它适用于任何天数。将N
替换为3
。
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添加到结果中。
答案 2 :(得分:0)
试试这个。我没有机会测试它,因为sqlfiddle不起作用,但一般的想法是通过分别向1
添加2
和start date
天来再增加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
答案 3 :(得分:0)
此查询使用双重自我联接来查找第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'
答案 4 :(得分:0)
工作正常......
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