逻辑选择可用资源

时间:2014-04-03 17:57:29

标签: php mysql sql

我现在已经把头撞到墙上几个小时了。

我正在为我公司的资源调度系统工作。我正在尝试提出一个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'将产生所需的结果。

我遇到问题的方法是如何排除1000110002。如果我选择2014-05-04BETWEEN starTDate AND endDate2014-05-07BETWEEN startDate and endDate的所有记录,则最终返回1000110002两行。我可以在一个查询中对这两行进行比较,以便我可以看到10002的结束日期和开始日期之间存在差距,但10001没有吗?

更新 我应该说我正在寻找可用资源的总数。并且,根据要求,这是一个sqlfiddle http://sqlfiddle.com/#!2/7035b/2

1 个答案:

答案 0 :(得分: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

迭代日期的想法