SQL获取在给定时间间隔内连续X天可用的ID
在SQL表中,我使用StartDate/EndDate列保留各种资源的预订:SQL获取在给定时间间隔内连续X天可用的ID,sql,Sql,在SQL表中,我使用StartDate/EndDate列保留各种资源的预订: ResourceID, StartDate, EndDate ----------------------------------- 1 2009-01-01 2009-01-05 1 2009-01-07 2009-01-10 2 2009-01-03 2009-01-18 我需要生成一个列表,列出给定时间间隔内至少连续X天可用的所有资源
ResourceID, StartDate, EndDate
-----------------------------------
1 2009-01-01 2009-01-05
1 2009-01-07 2009-01-10
2 2009-01-03 2009-01-18
我需要生成一个列表,列出给定时间间隔内至少连续X天可用的所有资源:即从2009-01-01到2009-01-20,X=5个连续天
例如,对于ResourceID=1,最大可用时间间隔为2009-01-10=>2009-01-20,因此这符合条件,但对于ResourceID=2,没有5天的可用时间间隔。有一个是2009-01-01=>2009-01-03,另一个是2009-01-18=>2009-01-20,都不够长
编辑:
根据Quassnoi的回答,我添加了一些修改来处理一些边缘情况:资源不带保留,或者保留跨越整个查找周期
这看起来像是最终结果。谢谢你的帮助
WITH avRows AS (
SELECT a.ID as aid,startDate , endDate , ROW_NUMBER() OVER (PARTITION BY ResourceID ORDER BY endDate ) AS rn
FROM tblResources a left outer join tblReservations b
on b.ResourceID = a.ID and (startDate BETWEEN '2009-01-01' AND '2009-01-20' OR endDate BETWEEN '2009-01-01' AND '2009-01-20' )
where a.ID NOT IN (select distinct ResourceID from tblReservations where (startDate <'2009-01-01' AND endDate > '2009-01-20' ))
)SELECT DISTINCT COALESCE(rs.aid, rp.aid)
FROM avRows rs FULL JOIN avRows rp ON rs.aid = rp.aid AND rp.rn = rs.rn - 1
WHERE DATEDIFF(day, COALESCE(rp.endDate , '2009-01-01'), COALESCE(rs.startDate , '2009-01-20')) >= 5
更新2:
更详细的解释和性能测试:
适用于SQL Server、Oracle和PostgreSQL 8.4
在MySQL中工作
你需要知道具体的日期吗,还是只有一个可用的日期?只是一个间隔是可用的。不管是有多个间隔还是什么时候,它都能工作!我知道有个“吻你”的按钮。把我从痛苦的夜晚救了出来
SELECT resourceID
FROM mytable
WHERE startDate BETWEEN '2009-01-01' AND '2009-01-20'
AND DATEDIFF(day, CASE WHEN endDate < '2009-01-20' THEN endDate ELSE '2009-01-20' END, startDate) >= 5
UNION
SELECT resourceID
FROM mytable
WHERE endDate BETWEEN '2009-01-01' AND '2009-01-20'
AND DATEDIFF(day, endDate, CASE WHEN startDate > '2009-01-01' THEN startDate ELSE '2009-01-01' END) >= 5
WITH rows AS
(
SELECT ResourceID, StartDate, EndDate, ROW_NUMBER() OVER (PARTITION BY ResourceID ORDER BY EndDate) AS rn
FROM mytable
WHERE StartDate BETWEEN '2009-01-01' AND '2009-01-20'
AND EndDate BETWEEN '2009-01-01' AND '2009-01-20'
)
SELECT DISTINCT COALESCE(rs.ResourceID, rp.ResourceID)
FROM rows rs
FULL JOIN
rows rp
ON rs.ResourceID = rp.ResourceID
AND rp.rn = rs.rn - 1
WHERE DATEDIFF(day, COALESCE(rp.EndDate, '2009-01-01'), COALESCE(rs.StartDate, '2009-01-20')) >= 5