1

我有两个数据库表,一个存储属性,另一个存储属性的预订。这是表结构的简化版本:

property
+-------------------+--------------+
| Field             | Type         |
+-------------------+--------------+
| id                | int(11)      |
| status            | int(1)       |
| title             | varchar(150) |
+-------------------+--------------+

booking
+-------------------+--------------+
| Field             | Type         |
+-------------------+--------------+
| id                | int(11)      |
| status            | int(1)       |
| property_id       | int(11)      |
| start_date        | date         |
| end_date          | date         |
+-------------------+--------------+

我有一个带有开始和结束日期的搜索表单,以查看在给定时间段内可用的属性。例如“2012-12-01 和 2012-12-07 之间有哪些房产可供出租”。

我有以下在一定程度上有效的 SQL:

SELECT p.id, p.title FROM property p WHERE p.status=1 AND p.id NOT IN (SELECT 
b.property_id FROM booking b WHERE (b.status=1 OR b.status=2 OR b.status=3 OR 
b.status=6) AND NOT (b.enddate < '2013-05-30' OR b.startdate > '2013-05-24')) 
ORDER BY p.title ASC

问题是,它不处理日期的重叠。如果搜索的是现有预订中的日期范围,则 SQL 可以正常工作并且不会返回该属性。但是,如果搜索日期与预订日期重叠,则仍会返回属性,即使它们是在搜索期间的一部分中被预订的。

我在这里设置了一个 SQL 小提琴:http ://sqlfiddle.com/#!2/d02e1 /4 - 有 5 个查询 - 前 2 个工作正常。我需要返回的属性如下:

  • 查询 1(工作) - 1、2 和 3
  • 查询 2(工作)- 2 和 3
  • 查询 3(不工作) - 2 和 3
  • 查询 4(不工作) - 2 和 3
  • 查询 5(不工作) - 2 和 3

非常感谢任何帮助或建议。

更新;

我想我的措辞可能有点不清楚。我要做的是获取在给定日期范围(搜索日期)内可供出租的房产列表。如果出现以下情况,则属性将不可用;搜索日期在现有预订日期范围内,或在任一端重叠。如果在搜索日期之间的任何时间段内都没有预订,则该物业是可用的。

4

2 回答 2

0

在这里设法解决它是小提琴:http ://sqlfiddle.com/#!2/d02e1/64

于 2012-12-04T19:01:18.020 回答
0

需要这样的东西吗?:

SELECT p.id, p.title 
FROM property p 
WHERE p.status=1 AND p.id NOT IN (
SELECT b.property_id 
    FROM booking b 
    WHERE (b.status IN (1, 2, 3, 6)) 
        AND (b.end_date BETWEEN '2012-12-01' AND '2012-12-30'
        OR b.start_date BETWEEN '2012-12-01' AND '2012-12-30')
) 
ORDER BY p.title ASC;

它返回 2 和 3

于 2012-12-04T16:41:04.237 回答