首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sql服务器日期递归

sql服务器日期递归
EN

Stack Overflow用户
提问于 2013-11-25 20:43:18
回答 1查看 151关注 0票数 1

基于另一个问题Server:如何将一系列连续的开始和结束日期时间转换为单个开始-结束范围?

我搜索一种递归的方法来获得最后的停机日期。我有三个停机时间链接。我想知道什么时候有我的服务。

代码语言:javascript
复制
Sample
    DECLARE @Downtime AS TABLE(id int, beginDT datetime, endDT datetime)
    INSERT INTO @Downtime VALUES('a','09:00','11:00')
    INSERT INTO @Downtime VALUES('b','10:00','12:00')
    INSERT INTO @Downtime VALUES('c','12:00','13:00')
    INSERT INTO @Downtime VALUES('d','15:00','16:00')


DECLARE @TimeParam AS DATETIME
SET @TimeParam ='1900-01-01 11:00:00.000'

11:00,我正处于停工状态(id=1或2,没关系)。我的问题是,“服务何时可用(不停机)?”

样品上的答案是13点。因为我们的停机时间从9到11 (id=1),id=2给我们11到12,id=3显示12到13。所以,它将从9降到13。

我需要一个sql查询才能找到它。一个递归,而开始/结束是在另一个结束之间。

我尝试过这样的方法,但它的语法是非法的。

代码语言:javascript
复制
;WITH myDates(beginDT,endDT)
AS
(
    SELECT beginDT, enddt
    FROM @Downtime D1
    WHERE @TimeParam BETWEEN begindt AND endDT

    UNION ALL

    SELECT beginDT, endDT 
    FROM @Downtime D2
    WHERE 
        (SELECT TOP 1  Max(enddt)
        FROM myDates )      
        BETWEEN begindt AND endDT
)
SELECT * FROM myDates 

更多样本

代码语言:javascript
复制
    INSERT INTO @Downtime VALUES('e','12:00','17:00') 
    INSERT INTO @Downtime VALUES('f','15:00','19:00') 
    INSERT INTO @Downtime VALUES('g','19:00','20:00') 
    INSERT INTO @Downtime VALUES('h','20:00','21:00') 
    INSERT INTO @Downtime VALUES('i','21:00','22:00') 
    INSERT INTO @Downtime VALUES('j','22:00','23:00')
    INSERT INTO @Downtime VALUES('k','23:00','23:01')
    INSERT INTO @Downtime VALUES('l','22:00','23:05')
    INSERT INTO @Downtime VALUES('m','22:00','23:06')
    INSERT INTO @Downtime VALUES('n','22:00','23:05')
    INSERT INTO @Downtime VALUES('o','22:00','23:17')
    INSERT INTO @Downtime VALUES('p','23:17','23:22')
    INSERT INTO @Downtime VALUES('q','23:22','23:23')
    INSERT INTO @Downtime VALUES('r','23:25','23:30')

停机时间应该是23点23分。

EN

回答 1

Stack Overflow用户

发布于 2013-12-11 04:17:42

我假设@DownTime中的date列实际上不仅仅是时间,因为这意味着它们默认为1/1/1900。如果这个假设是错误的,请告诉我。

SQL Fiddle演示

代码语言:javascript
复制
DECLARE @TimeParam AS DATETIME
SET @TimeParam ='1900-01-01 11:00:00.000'


;WITH myDates(id, begindt, endDT)
AS
(
    Select top 1 id, begindt, EndDT    
    from DownTime 
    where @TimeParam not between beginDT and endDT        

    UNION ALL

    SELECT DownTime.id, DownTime.beginDT, DownTime.endDT    
    FROM myDates D2,DownTime
    Where D2.endDT >= DownTime.beginDT
    and D2.beginDT <= DownTime.endDT    
    and DownTime.ID > D2.ID
)
Select top 1 EndDT from myDates order by endDT desc

这也是假设表中的数据已经按照beginDT排序(正如您在示例数据中提供的那样)。如果情况并非如此,则可能需要对记录进行排序并将它们插入临时表中,并修改CTE以使用临时表。您可以尝试将ROW_NUMBER添加到CTE中,但这对于递归CTE来说有点棘手。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20202899

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档