从表中选择*,其中所需期间与现有期间不重叠

时间:2015-09-24 18:16:47

标签: mysql sql

我有一张表,其中包含每条记录的记录和一段时间,例如预订。所以我的记录看起来像这样:

Table-reservations
id  room    datefrom        dateto
1   'one'   '2015-09-07'    '2015-09-12'
2   'two'   '2015-08-11'    '2015-09-02'
3   'three' '2015-06-11'    '2015-06-14'
4   'two'   '2015-07-30'    '2015-08-10'
5   'four'  '2015-06-01'    '2015-06-23'
6   'one'   '2015-03-21'    '2015-03-25'
...
n   'nth'   '2015-06-01'    '2015-07-03'

还有一张桌子,房间里有ID,房间号和房型,如下:

Table-rooms
idrooms   room      roomtype
1         'one'     'simple'
2         'two'     'simple'
3         'three'   'double'
...
nx        'nth'     'simple'

正如您所看到的,有些房间会出现多次,但会有不同的时段,因为它们是在不同的时段预订的。 我需要通过SQL获得的是在给定时间段内可用的房间列表。

类似于(伪代码):

Select room from table where there is no reservation on that room between 2015-08-13 and 2015-08-26

我该怎么做?

所以我将有一个日期和一个todate,我将不得不在查询中使用它们。

你们中间有人可以给我一些指示吗?

现在我使用以下sql获取现在可用的房间列表

select * from rooms
 where idrooms not in
 (
 select idroom from rezervations where
 ((date(now())<=dateto and date(now())>=datefrom)or(date(now())<=dateto and date(now())<=datefrom))
 )
 order by room

5 个答案:

答案 0 :(得分:2)

这可能更容易理解。

假设你有另一张房间用桌。

SELECT * 
FROM rooms 
WHERE NOT EXISTS (SELECT id 
                  FROM reservations 
                  WHERE reservations.room = rooms.id 
                    AND datefrom >= '2015-08-13' 
                    AND dateto <= '2015-08-26')

答案 1 :(得分:1)

您需要检查记录是否存在,其中'date from'小于或等于您范围内的结束日期,'date to'大于或等于您范围内的开始日期。

select t1.room
from reservations t1
where not exists (
  select *
  from reservations t2
  where t2.room = t1.room
  and t2.datefrom <= '2015-08-26'
  and t2.dateto >= '2015-08-13'
)
group by room

您可以在此处试用:http://sqlfiddle.com/#!9/cbd59/5

我是网站的新用户,因此不会让我发表评论,但我认为第一个答案的问题是应该颠倒运营商。

如前一条评论所述,只有所有房间都有预订记录才有用。如果没有,最好从您的房间表中选择:http://sqlfiddle.com/#!9/0b96e/1

select room
from rooms
where not exists (
  select *
  from reservations
  where rooms.room = reservations.room
  and reservations.datefrom <= '2015-08-26'
  and reservations.dateto >= '2015-08-13'
)

答案 2 :(得分:0)

SELECT a.room
FROM yourTable a
WHERE a.room NOT IN (
    SELECT DISTINCT( b.room )
    FROM yourTable b
    WHERE datefrom >= '2015-08-13'
        OR dateto <= '2015-08-26'
);

它应该尽我所能地发挥作用。如果没有;你能提供一个检查数据吗?

答案 3 :(得分:0)

使用此SO answer

考虑

  

range1:r11 r12 [inputfromDate inputToDate]
  range2:r21 r22 [datefromColumn datetoColumn]

     

如果r11&lt; = r22&amp;&amp; r21&lt; = r12,则范围重叠。

有6种可能的情况,其中两个范围可以重叠。但是上述两个条件本身处理了所有6种可能性。

如果上述条件匹配则表示日期重叠。所以我使用not in来获取剩余的条目。

select * from <table-name> where id not in (
   select id from <table-name> where 
   :inputfromDate <= datetoColumn and datefromColumn <= :inputToDate
)

答案 4 :(得分:0)

你可以试试这个:

select * from rooms
    where room not in(
    select room from reservations
    where '2015-09-16' >= datefrom  
    and '2015-09-16' <=dateto 
    and '2015-09-21' >= dateto
)

古德勒克!