2013-11-20 35 views
5

我試圖找到一天的空閒時間段,但是我被困在正確的查詢上。 開放時間或日期在每天的9:00至22:00之間運行,以下查詢在當天返回正確的數據,除非第一天的預訂時間爲10:00,否則它不會返回未預訂的時間段9:00和10:00,如果從21:30至21:40預訂,則不會顯示當天的最後一個空閒時間。Mysql查找預約之間的空閒時間

在一分鐘得到這個每一天和set_id我不得不創建一天開始和一天結束1分鐘插入代表插入爲id = 1和id = 6。

我想不必創建這兩個刀片每天脫身,每個SET_ID

CREATE TABLE bookings 
(`id` int, `time_from` datetime, `time_to` datetime, `set_id` int); 


INSERT INTO bookings 
    (`id`, `time_from`, `time_to`, `set_id`) 
VALUES 
    (1, '2013-11-20 08:59:00', '2013-11-20 09:00:00', 6), 
    (2, '2013-11-20 09:10:00', '2013-11-20 10:00:00', 6), 
    (3, '2013-11-20 11:10:00', '2013-11-20 11:30:00', 6), 
    (4, '2013-11-20 12:00:00', '2013-11-20 12:40:00', 6), 
    (5, '2013-11-20 16:20:00', '2013-11-20 16:50:00', 6), 
    (6, '2013-11-20 22:00:00', '2013-11-20 22:01:00', 6) 
; 

SELECT Available_from, Available_to 
FROM (
    SELECT @lasttime_to AS Available_from, time_from AS Available_to, @lasttime_to := time_to 
    FROM (SELECT time_from, time_to 
      FROM bookings 
      WHERE set_id = 6 
      AND time_to >= '2013-11-20 08:59' 
      AND time_from < '2013-11-20 22:01' 
     ORDER BY time_from) e 
    JOIN (SELECT @lasttime_to := NULL) init) x 
WHERE Available_to > DATE_ADD(Available_from, INTERVAL 9 MINUTE); 


|  AVAILABLE_FROM |     AVAILABLE_TO | 
|---------------------|---------------------------------| 
| 2013-11-20 09:00:00 | November, 20 2013 09:10:00+0000 | 
| 2013-11-20 10:00:00 | November, 20 2013 11:10:00+0000 | 
| 2013-11-20 11:30:00 | November, 20 2013 12:00:00+0000 | 
| 2013-11-20 12:40:00 | November, 20 2013 16:20:00+0000 | 
| 2013-11-20 16:50:00 | November, 20 2013 22:00:00+0000 | 

任何幫助,將不勝感激。

http://www.sqlfiddle.com/#!2/b30a0/2

CREATE TABLE `days` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `date` date NOT NULL, 
    `time_from` datetime NOT NULL, 
    `time_to` datetime NOT NULL, 
    `step` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; 


INSERT INTO `days` (`id`, `date`, `time_from`, `time_to`, `step`) 
VALUES 
    (1, '2013-11-20', '2013-11-20 09:00:00', '2013-11-20 22:00:00', 10), 
    (2, '2013-11-21', '2013-11-21 09:00:00', '2013-11-21 22:00:00', 10); 

靠近一點!

INSERT INTO `bookings` (`id`, `date`, `time_from`, `time_to`, `set_id`, `name`, `email`, `telephone`, `amount`, `notes`, `is_paid`, `is_booked`) 
VALUES 
    (25, '2013-11-20', '2013-11-20 09:10:00', '2013-11-20 09:30:00', 1, '', '', '', NULL, NULL, 0, 0), 
    (26, '2013-11-20', '2013-11-20 10:30:00', '2013-11-20 11:30:00', 1, '', '', '', NULL, NULL, 0, 0), 
    (27, '2013-11-20', '2013-11-20 12:30:00', '2013-11-20 13:20:00', 1, '', '', '', NULL, NULL, 0, 0), 
    (29, '2013-11-20', '2013-11-20 15:00:00', '2013-11-20 16:40:00', 1, '', '', '', NULL, NULL, 0, 0); 

這就是我得到

availableFrom   availableTo 
9:00     2013-11-20 09:10:00 
2013-11-20 09:30:00  2013-11-20 10:30:00 
2013-11-20 11:30:00  2013-11-20 12:30:00 
9:00     2013-11-20 15:00:00 
2013-11-20 15:00:00  22:00 
+0

感謝這裏將我需要的響應工會? – Tim

+0

我確實有一個天數表,id,date,time_from,time_to,步驟 – Tim

+0

因此id = 1,date = 2013-11-20,time_from = 2013-11-20 09:00:00,time_to = 2013-11- 20,step = 10 – Tim

回答

0

一個可能的選擇是左加入表本身沿着這些路線的東西:

select (case when ltime_to is null then '9:00' else ltime_to end) as availableFrom, 
rtime_from as availableTo 
from (select l.time_to as ltime_to, r.time_from as rtime_from from bookings r 
left join bookings l on l.id=r.id-1) lr 
union 
select max(time_from) as availableFrom, '22:00' as availableTo from bookings 
+0

沒有這種方式返回什麼。 – Tim

+0

啊我明白了,沒有立即得到你所做的。其中一種簡單的方法就是在一天的第一時間插入一個可以啓動和停止的虛擬預訂,然後您可以將其作爲第一次使用。其他選項,如果你保證你的表格有不重疊的連續時間段,可以做lEFT在l.id = r.id-1上自行加入表格,然後使用以前的time_from或day_from作爲time_from。 – Ashalynd

+0

非常感謝,假的條目是上面插入的第一個和最後一個條目 - id的1和6,你會注意到他們只有1分鐘的預訂。這是我試圖擺脫的,因爲我不得不每天爲6個場地或set_id創建這些虛假預訂。並認爲必須有一種方法來將開始和結束時間集成到查詢中,因此我不必執行僞造插入。 (我喜歡虛名!)我可以使用天桌的開始和結束時間?謝謝 – Tim