2012-11-16 20 views
4

對於類似的話題,我們提出了幾個問題,但是我找不到解決這個問題的方法,並且非常感謝您的意見。MySQL/PHP - 查找可用時間段

我正在致力於預訂引擎,用戶可以在線預訂某些服務。我被困在特定的一天(或一週)內查找並顯示可用時間段。我知道所需時間段的長度(例如1小時)以及時段可預訂的營業時間(例如09:00h - 18:00h)。另外我有一個MySQL表,存儲已經存在的約會。有關我的問題的列是這樣的:

id start (datetime)  end (datetime) 
1 '2012-11-16 13:00:00' '2012-11-16 14:30:00' 
2 '2012-11-16 15:00:00' '2012-11-16 16:00:00' 
3 '2012-11-17 12:00:00' '2012-11-16 15:45:00' 
4 '2012-11-17 13:00:00' '2012-11-16 16:15:00' 
... 

現在給出上述信息,我無法找到檢索可用時隙的列表,一個好的解決方案(在MySQL或PHP)。還有一個條件:時間段只能按季度開始。 IE瀏覽器。對於上面示例性數據,第16天可用的一小時時隙將是:
09:00,09:15,09:30,09:45,10:00,...,12:00,16:00, 16:15,...,17:00。

請注意,即使可能存在重疊次數(如樣本數據中),可用時間段也不能重疊。

您認爲最好的方法是什麼?

+0

重疊的條件是什麼?他們是與一個人預訂服務,還是可以同時進行多個預約? – Lucas

+0

這是一個人的預訂。普通用戶只能預訂100%免費的時間段,即。沒有重疊。管理員有一個不同的/更復雜的日曆,允許重疊(因爲他們可能知道他們可以在某些情況下處理重疊)。對於上面的問題,我想唯一重要的一點是數據庫表中可能存在重疊的插槽,系統應該嘗試查找可用性。 – j2dab

回答

6
SELECT a.end AS free_after 
FROM bookings a 
WHERE NOT EXISTS (
    SELECT 1 
    FROM bookings b 
    WHERE b.start BETWEEN a.end AND a.end + INTERVAL your_duration HOURS 
) 
AND a.end BETWEEN start_of_search_window AND end_of_search_window; 

你只需要爲your_duration(整數),start_of_search_window(日期時間)和end_of_search_window(日期時間)提供值。

如果你想花俏....

SELECT free_from, free_until 
FROM (
    SELECT a.end AS free_from, 
    (SELECT MIN(c.start) 
    FROM bookings c 
    WHERE c.start > a.end) as free_until 
    FROM bookings a 
    WHERE NOT EXISTS (
    SELECT 1 
    FROM bookings b 
    WHERE b.start BETWEEN a.end AND a.end + INTERVAL your_duration HOUR 
) 
    AND a.end BETWEEN start_of_search_window AND end_of_search_window 
) 
ORDER BY free_until-free_from 
LIMIT 0,3; 

會給你窗內三個最短可用插槽(即最接近目標的大小)。

+1

完美,非常感謝!這正是我期待的!你認爲也可以得到所有可用插槽的結果嗎?在上面的示例中,一個結果行是:2012-11-16 16:00:00 - 2012-11-17 12:00:00。相反,我更喜歡包含時間段的多行,如:2012-11-16 16:00:00 - 2012-11-16 17:00:00和2012-11-16 17:00:00 - 2012 -11-16 18:00:00依此類推......或者你會使用PHP將整個空閒時間分配給插槽嗎? – j2dab

+1

還有一件事,我已經玩弄了你的解決方案,並發現了一個我自己無法解決的棘手問題。如果我在start_of_search_window 2012-11-16 00:00:00和end_of_search_window 2012-11-18 00:00:00使用您的語句,它會在2012-11-16 00:00:00和2012-11- 16 13:00:00。 IE瀏覽器。它只會在找到第一個約會之後以free_from開頭。你能指出我如何解決這個錯誤的正確方向..? – j2dab

+0

從概念上講,它是微不足道的 - 只需用包含虛擬約會結尾的vierw替換「預訂a」表即可 - 但SQL更復雜。 – symcbean