2014-04-03 50 views
0

現在,我已經把頭撞到了牆壁上,現在已經有幾個小時了。選擇可用資源的邏輯

我正在爲我公司開發資源調度系統。我試圖想出一個SQL查詢,它可以讓我找出資源何時可用於某個事件。

我覺得來形容它的最好方法是用一個例子所以這裏有雲:

鑑於表Availability有開始和結束日期

TABLE Availability 
| id | resourceId | startDate | endDate | 
| 100 | 10000  | 2014-04-15 | 2014-05-31 | 
| 101 | 10001  | 2014-04-01 | 2014-05-04 | 
| 102 | 10001  | 2014-05-05 | 2014-05-10 | 
| 103 | 10002  | 2014-04-05 | 2014-05-05 | 
| 104 | 10002  | 2014-05-07 | 2014-05-31 | 

並給予我需要找到所有資源可從2014-05-04 - 2014-05-07

在給定的數據,可用資源的總數目爲2。

資源10000顯然可用,因爲它的開始和結束日期跨越了所需的範圍。

資源10001可用,因爲它有兩個條目結束,然後開始連續的日子。

資源10002不可用,因爲2014-05-06在其可用性上​​存在差距。

到達10000可用很容易,因爲簡單的查詢SELECT * FROM availability WHERE startDate <= '2014-05-04' AND endDate >= '2014-05-07'將產生所需的結果。

我遇到麻煩的是如何排除10001,排除10002。如果我選擇2014-05-04BETWEEN starTDate AND endDate2014-05-07BETWEEN startDate and endDate的所有記錄,我最終將返回1000110002的兩行。我可以在單個查詢中比較這兩行,以便我可以看到10002的結束日期和開始日期之間有差距,但是10001沒有一個?

更新 我應該說我正在尋找可用資源的總數。並且,根據要求,這裏是一個sqlfiddle http://sqlfiddle.com/#!2/7035b/2

+0

考慮提供適當的DDL(和/或sqlfiddle)連同SET – Strawberry

+0

期望的結果似乎並沒有借給本身以及對單個SELECT語句;對於每種資源,您需要遍歷可用的日期範圍,合併重疊或相鄰的條目,以構建可用性的真實圖景。一個想法是,如果粒度是日期而不是時間,並且約束是正確的,那麼您可以檢查(在您的示例中)5-04和5-05以及5-06和5-07中可用的資源以及每個是一個簡單的查詢...然後一起加入結果。 – RobP

+0

Ares您能夠記錄資源何時不可用,而不是它們何時可用? _I.e._是否永久可用,除非保留?如果是的話,這個問題將會被簡化。 –

回答

0

這是一個使用RobP的想法的查詢。驗證它是否適用於示例場景。

WITH dates AS (
    SELECT CAST('2014-05-04' AS DATETIME) 'date' 
    UNION ALL 
    SELECT DATEADD(dd, 1, t.date) 
     FROM dates t 
     WHERE DATEADD(dd, 1, t.date) <= '2014-05-07') 
SELECT resourceid 
FROM availability, dates d 
WHERE d.date >= startdate and d.date <= enddate 
GROUP BY resourceid 
HAVING COUNT(*) >= DATEDIFF("d",'2014-05-04','2014-05-07')+1 

有大約通過日期從迭代的想法Generate a resultset of incrementing dates in TSQL

+0

順便說一下,我在SQL Server 2008 R2上測試了上述內容。您可能需要爲MySQL找到等效的DATEADD函數或WITH構造 –