2015-07-10 84 views
0

這似乎是一個典型問題,但我無法找到對此問題的答案。預訂日曆抵達和出發日期

我有一個預約表:

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 

你會看到,我已證明,出發日期是到達日期,反之亦然

添加日期之前我檢查的日期範圍不會與表格中的日期相沖突,因此當出發人員將要離開時允許出發日期成爲抵達日期非常重要,以便在我查看錶格中的日期時向Arri_date添加日期,並且使用此SQL從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日是離開日期。

任何幫助,將不勝感激

我應該還提到,我也有保存阻塞日期「booking_prev」,因此類似的查詢也將在使用前檢查塊日期那些在預訂表的表他們進入。

+0

有沒有必要先檢查。事實上,這可能會適得其反,因爲有人可能會在檢查和做下一步工作之間插入一個值。 – Strawberry

+0

是的,雖然日期只會顯示,並允許預訂,如果他們不在預訂表中,我仍然需要一種檢查日期範圍的方法是有效的第一...請看看我已經添加。 – simmo

+0

你不需要先檢查。 (除非使用交易),支票可以並且應該在插入過程中發生。 – Strawberry

回答

1

考慮以下...

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查詢可能是這樣的......

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 | 
+------------+------------+ 

...但你並不需要先檢查。我故意寫的按這樣的方式檢查可能發生的INSERT的一部分......

INSERT INTO my_table (arrive_date,depart_date) 
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; 

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 | 
|  4 | 2015-07-23 | 2015-07-24 | 
+---------+-------------+-------------+ 
+0

非常感謝您抽出寶貴時間來展示解決方案,插入程序就是這麼做的。只是幾個問題,這對我來說是新的,雖然它起作用,但我不能跟隨(SELECT)x做什麼,並且似乎無法找到解釋。因爲我只想插入申請如果日期不在插入表和另一個,我會只是添加一個OR 從(選擇2)x左JOIN my_other表z ON z.arrive_date <'2015年7月24日' AND z.depart_date>'2015-07-23'WHERE z.book_id IS NULL:最後,我最初的想法是檢查fbefore插入,所以我可以告訴用戶錯誤。 – simmo

+0

這真是個黑客。我只需要一個用於JOIN的虛表表格實例。 x是子查詢的別名。 – Strawberry

-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,注)選擇58, '2015-07-28','2015-07-29','我的筆記'FROM(SELECT 1)x LEFT JOIN booking_prevent y ON y.from_date <'2015-07-29'AND y.to_date>'2015- 07-28'和y.unit_id = 58 WHERE y.booking_prevent_id IS NULL LIMIT 1

這很有效,但我有點卡住瞭如何才能對條目進行更新,但只進行更改...再次,如果它是有效的。這是我有什麼,這是在黑暗中刺:

更新booking_prevent SET(unit_id,from_date,to_date,note)SELECT 58,'2015-07-20','2015-07-26','更新備註'FROM(SELECT 1)x LEFT JOIN booking_prevent y ON y.from_date <'2015-07-26'AND y.to_date>'2015-07-20'and y.unit_id = 58 WHERE y.booking_prevent_id IS NULL WHERE booking_prevent_id = 466限制1

任何指針,將不勝感激。

+0

只要沒有人在檢查時提交插頁。 – Strawberry

+0

時間也是線性的 - 我的查詢利用了這個事實 – Strawberry