我现在已经把头撞到墙上几个小时了。
我正在为我公司的资源调度系统工作。我正在尝试提出一个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-04
为BETWEEN starTDate AND endDate
或2014-05-07
为BETWEEN startDate and endDate
的所有记录,则最终返回10001
和10002
两行。我可以在一个查询中对这两行进行比较,以便我可以看到10002
的结束日期和开始日期之间存在差距,但10001
没有吗?
更新 我应该说我正在寻找可用资源的总数。并且,根据要求,这是一个sqlfiddle http://sqlfiddle.com/#!2/7035b/2
答案 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
迭代日期的想法