Sql server SQL折叠顺序时间序列集

Sql server SQL折叠顺序时间序列集,sql-server,tsql,Sql Server,Tsql,在MSSQL中,我有一组具有开始和结束时间的任务 我想做的是将顺序任务折叠在一起。 所以我对顺序的定义是TaskEndDate等于下一个TaskStartDate的开始,时间上没有间隔 在下面的数据集中,21:00到21:40是一个序列,然后是22:00到22:20和23:20到00:00 TaskStartDate TaskEndDate 2008-09-01 21:00:00.000 2008-09-01 21:05:00.000 2008-09-01 21:05:0

在MSSQL中,我有一组具有开始和结束时间的任务

我想做的是将顺序任务折叠在一起。
所以我对顺序的定义是TaskEndDate等于下一个TaskStartDate的开始,时间上没有间隔

在下面的数据集中,21:00到21:40是一个序列,然后是22:00到22:20和23:20到00:00

TaskStartDate             TaskEndDate
2008-09-01 21:00:00.000 2008-09-01 21:05:00.000
2008-09-01 21:05:00.000 2008-09-01 21:10:00.000
2008-09-01 21:10:00.000 2008-09-01 21:15:00.000
2008-09-01 21:15:00.000 2008-09-01 21:20:00.000
2008-09-01 21:20:00.000 2008-09-01 21:25:00.000
2008-09-01 21:25:00.000 2008-09-01 21:30:00.000
2008-09-01 21:30:00.000 2008-09-01 21:35:00.000
2008-09-01 21:35:00.000 2008-09-01 21:40:00.000
2008-09-01 22:00:00.000 2008-09-01 22:05:00.000
2008-09-01 22:05:00.000 2008-09-01 22:10:00.000
2008-09-01 22:10:00.000 2008-09-01 22:15:00.000
2008-09-01 22:15:00.000 2008-09-01 22:20:00.000
2008-09-01 23:20:00.000 2008-09-01 23:25:00.000
2008-09-01 23:25:00.000 2008-09-01 23:30:00.000
2008-09-01 23:30:00.000 2008-09-01 23:35:00.000
2008-09-01 23:35:00.000 2008-09-01 23:40:00.000
2008-09-01 23:40:00.000 2008-09-01 23:45:00.000
2008-09-01 23:45:00.000 2008-09-01 23:50:00.000
2008-09-01 23:50:00.000 2008-09-01 23:55:00.000
2008-09-01 23:55:00.000 2008-09-02 00:00:00.000

请随意使用CTE或其他MSSQL特定功能。

假设没有重复项重叠,则应这样做:

;WITH cteStart As (
    SELECT TaskStartDate,
        ROW_NUMBER() OVER(ORDER BY TaskStartDate) as N
    FROM YourTable y
    WHERE TaskStartDate NOT IN(SELECT TaskEndDate FROM YourTable y1)
), cteEnd As (
    SELECT TaskEndDate,
        ROW_NUMBER() OVER(ORDER BY TaskEndDate) as N
    FROM YourTable y
    WHERE TaskEndDate NOT IN(SELECT TaskStartDate FROM YourTable y1)
)
SELECT TaskStartDate, TaskEndDate
FROM cteStart as s
    JOIN cteEnd as e ON e.N = s.N

编辑:在最后一次选择时,将第二个“TaskStartDate”更改为“TaskEndDate”。

它并不漂亮。。。但这里有一些SQL似乎是有效的。只需将[Tasks]替换为表名即可

SET NOCOUNT ON

DECLARE @date DATETIME
DECLARE @continueLoop INT
DECLARE @continueInnerLoop INT

DECLARE @tmp TABLE (
    [Start] [DateTime] NOT NULL , 
    [End] [DateTime] NOT NULL
)

SET @continueLoop = 1

WHILE @continueLoop <> 0 BEGIN
    INSERT INTO @tmp
    SELECT TOP 1 [TaskStartDate], [TaskEndDate]
    FROM [dbo].[Tasks]
    WHERE [TaskStartDate] > ISNULL((SELECT TOP 1 [End] FROM @tmp ORDER BY [End] DESC), '19000101')
    SET @continueInnerLoop = @@ROWCOUNT

    WHILE @continueInnerLoop <> 0 BEGIN
        UPDATE @tmp
        SET [End] = Tasks.[TaskEndDate]
        FROM @tmp, [dbo].[Tasks] 
        WHERE [End] = Tasks.[TaskStartDate]
    SET @continueInnerLoop = @@ROWCOUNT
    END

    SELECT @continueLoop = COUNT(*)
    FROM [dbo].[Tasks]
    WHERE [TaskStartDate] > ISNULL((SELECT TOP 1 [End] FROM @tmp ORDER BY [End] DESC), '19000101')
END

SELECT * FROM @tmp

或者,您也可以使用此解决方案:


您的查询将是平凡的

3序列?21:00至21:40,22:00至22:20,23:20至00:00是的,抱歉更正了问题。底部选择应为:选择TaskStartDate,TaskEndDate从cteStart作为s加入cteEnd作为e上的e。N=s.N
[TaskStartDate], [TaskEndDate]
2008-09-01 21:00:00.000, 2008-09-01 21:40:00.000
2008-09-01 22:00:00.000, 2008-09-01 22:20:00.000
2008-09-01 23:20:00.000, 2008-09-02 00:00:00.000