2013-02-13 70 views
1

预订表:SQL - 如何列出在某些日期范围内未保留的属性?

id | fk_property_id |  arrival  |  departure  
------+----------------+---------------------+--------------------- 
1 |   1 | 2013-01-11 14:00:00 | 2013-09-07 10:00:00 
2 |   1 | 2013-02-12 14:00:00 | 2013-09-07 10:00:00 
3 |   1 | 2013-03-29 14:00:00 | 2013-09-07 10:00:00 
4 |   2 | 2013-04-29 14:00:00 | 2013-09-07 10:00:00 
5 |   2 | 2013-05-29 14:00:00 | 2013-09-07 10:00:00 
6 |   3 | 2013-06-29 14:00:00 | 2013-09-07 10:00:00 

属性表:

id |       title       
-----+-------------------------------------------------------- 
1 | blah blah 
2 | blah blah 
3 | blah blah 
4 | blah blah 
5 | blah blah 
6 | blah blah 
7 | blah blah 
8 | blah blah 
9 | blah blah 
10 | blah blah 

我需要列出可用于特定日期范围性能。

例如用户输入日期范围: 到来:2013年6月29日14:00:00 出发:2013年7月14日10:00:00

,我需要列出所有不可─在那段时间租用房产。我怎么做?
我认为它应该是一个左连接 - 但我无法将其包围。

回答

2

这里是右侧条件:

select p.* 
from properties p left outer join 
    reservations r 
    on p.id = r.fk_property_id and 
     r.arrival < '2013-07-14 10:00:00' and 
     r.departure > '2013-06-29 14:00:00' 
where r.id is null 

这里是逻辑。首先,时间条件需要进入on条款。在where条款中,它们与left outer join冲突。

逻辑是,一个房间是可用的所有日期之前没有到达日期的晚些时候和没有离开后的第一次日期。这考虑了所有各种重叠可能性。

最后的where只是找到可用的属性,因为没有保留。

+0

+1 - 很好的答案 - 唯一正确的答案 – sgeddes 2013-02-13 04:41:53

1

有几种方法:

LEFT JOIN

SELECT p.id, p.title 
FROM properties p 
LEFT JOIN reservations r 
on p.id = r.fk_property_id 
where arrival < '2013-06-29 14:00:00' 
and departure > '2013-07-14 10:00:00' 
and r.id is null 

但是,因为你基本上执行反半连接,NOT EXISTS可能是你最好:

select p.id, p.title 
from properties p 
where NOT EXISTS (
    select 1 
     from reservations r 
      where where arrival > '2013-06-29 14:00:00' 
       and departure < '2013-07-14 10:00:00' 
       and p.id = r.fk_property_id); 
+0

在我看来,第一个例子将只涵盖用户输入范围完全落在db-reservation范围内的情况。但是,当用户输入的范围在预定范围内开始但结束于其外的情况下 - 所以日期重叠但不完全在彼此内部? – 2013-02-13 04:32:31

+0

哎呀。我翻转了测试 – swasheck 2013-02-13 04:55:14

0

您希望将IS NULL与您的LEFT OUTER JOIN表一起使用。这意味着在该特定属性的预订表中没有发现任何内容。

SELECT * 
FROM properties LEFT OUTER JOIN reservations ON properties.id =  reservations.fk_property_id AND a 
WHERE arrival > '2013-06-29 14:00:00' 
AND departure < '2013-07-14 10:00:00' 
AND reservations.arrival IS NULL 
+0

我不确定postgres如何处理'IS NULL'过滤器以及'arrival'日期的过滤器。否则看起来不错。 – swasheck 2013-02-13 04:24:48