预订日历到达&离开日期

时间:2015-07-10 17:01:17

标签: php mysql sql

这似乎是一个典型的问题,但我找不到这个问题的答案。

我有一张预订表:

book_id  |   arrive_date |   depart_date
1                 2015-07-20     2015-07-22 
2                 2015-07-22     2015-07-23  
3                 2015-07-19     2015-07-20  

您将看到我已经证明离开日期可以是到达日期,反之亦然

在添加日期之前,我检查日期范围是否与表格中的日期不一致,重要的是允许离开日期为该人员将要离开的到达日期,以便在我检查时允许表格中的日期我使用此SQL将日期添加到arrival_date并从depart_date中提取一天:

Select * From booking Where booking.unit_id = 58 
  And ( DATE_ADD(booking.from_date, INTERVAL 1 DAY) 
  BETWEEN '2015-07-23' AND '2015-07-24' 
   OR 
  DATE_SUB(booking.to_date, INTERVAL 1 DAY) 
   BETWEEN '2015-07-23' AND '2015-07-24' 
      OR '2015-07-23' 
   BETWEEN DATE_ADD(booking.from_date, INTERVAL 1 DAY) 
   AND DATE_SUB(booking.to_date, INTERVAL 1 DAY)) Limit 1  

当我添加第一个日期时,没有问题......与第二个和第三个相同,这是有效的,因为我在(20日和22日)之间输入了第一个日期范围。然后我尝试添加'2015-07-23'和'2015-07-24',使用上面的SQL检查,显然返回结果。我需要一种允许接受这些日期的方法,因为23日是depart_date。

任何帮助将不胜感激

我还应该提一下,我还有一个表格,其中包含阻止日期“booking_prev”,因此在输入之前,类似的查询也将用于检查预订表中的阻止日期。

2 个答案:

答案 0 :(得分:1)

考虑以下内容......

func

因此,SELECT可能看起来像这样......

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(book_id  INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,arrive_date DATE NOT NULL
,depart_date DATE NOT NULL
);

INSERT INTO my_table VALUES
(1,'2015-07-20','2015-07-22'),
(2,'2015-07-22','2015-07-23'),
(3,'2015-07-19','2015-07-20');

SELECT * FROM my_table;
+---------+-------------+-------------+
| book_id | arrive_date | depart_date |
+---------+-------------+-------------+
|       1 | 2015-07-20  | 2015-07-22  |
|       2 | 2015-07-22  | 2015-07-23  |
|       3 | 2015-07-19  | 2015-07-20  |
+---------+-------------+-------------+

...但你不需要先检查它们。我故意以这样的方式编写SELECT,以便检查可以作为INSERT的一部分发生...

SELECT '2015-07-22','2015-07-24' 
  FROM (SELECT 1) x 
  LEFT 
  JOIN my_table y
    ON y.arrive_date < '2015-07-24' AND y.depart_date > '2015-07-22'
 WHERE y.book_id IS NULL 
 LIMIT 1;
Empty set (0.00 sec)

SELECT '2015-07-23','2015-07-24' 
  FROM (SELECT 1) x 
  LEFT 
  JOIN my_table y
    ON y.arrive_date < '2015-07-24' AND y.depart_date > '2015-07-23'
 WHERE y.book_id IS NULL 
 LIMIT 1;
+------------+------------+
| 2015-07-23 | 2015-07-24 |
+------------+------------+
| 2015-07-23 | 2015-07-24 |
+------------+------------+

在实践中,根据您要提供的用户体验,您可能希望首先运行SELECT,以便用户可以立即查看哪些日期不可用,然后在它出现时运行INSERT进行预订 - 确保在用户预订中途时没有人抓住这些日期。

答案 1 :(得分:-1)

好吧,虽然接受的答案很好地完成了这项工作,但我仍然需要检查日期条目是否有效,主要是因为我在添加到阻止日期的表之前检查了主预订表中的日期。无论如何,跟随SQL,似乎做了我需要的所有检查:

Select * From booking Where booking.unit_id = 58 And ((booking.arrive_date < '2015-07-23' And booking.depart_date >= '2015-07-24') OR (booking.arrive_date <= '2015-07-23' And booking.depart_date > '2015-07-24') OR (booking.arrive_date >= '2015-07-23' And booking.depart_date <= '2015-07-24') OR ('2015-07-23' > booking.arrive_date And '2015-07-23' < booking.depart_date ) OR ('2015-07-24' > booking.arrive_date And '2015-07-24' < booking.depart_date )) Limit 1 

对于我给出的解决方案感到有点失望,因为它确实检查了表中的值,这是我的要求之一,尽管它对于实际插入并不是那么有效。

继续我已经扩展了已接受的答案,根据表格添加了更多我正在使用的字段,以阻止预订日期:

INSERT INTO booking_prevent(unit_id,from_date,to_date,note)SELECT 58,'2015-07-28','2015-07-29','My Note'FROM(SELECT 1)x LEFT JOIN booking_prevent y ON y .from_date&lt; '2015-07-29'AND y.to_date&gt; '2015-07-28'和y.unit_id = 58 WHERE y.booking_prevent_id IS NULL LIMIT 1

这非常有效,但我对如何对条目进行更新感到有些困惑,但是如果它有效,只会再次进行更改。这就是我所拥有的,这是在黑暗中刺伤:

UPDATE booking_prevent SET(unit_id,from_date,to_date,note)SELECT 58,'2015-07-20','2015-07-26','Updated Note'FROM(SELECT 1)x LEFT JOIN booking_prevent y ON y .from_date&lt; '2015-07-26'AND y.to_date&gt; '2015-07-20'和y.unit_id = 58 WHERE y.booking_prevent_id IS NULL WHERE booking_prevent_id = 466 LIMIT 1

任何指针都将不胜感激。