2009-06-04 359 views
2

在MSSQL中,我有一组具有开始和结束时间的任务。SQL Collapse连续时间序列集合在一起

我想要做的是将连续任务合并在一起。
所以我的顺序定义是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的特定功能。

+1

3序列? 21:00至21:40,22:00至22:20,23:20至00:00 – gbn 2009-06-04 08:59:01

+0

是的,对不起更正的问题。 – Jafin 2009-06-04 14:22:56

回答

3

假设没有重复的重叠,这应该这样做:

;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”。

+0

底部选择应显示为: SELECT TaskStartDate,TaskEndDate FROM cteStart as s JOIN cteEnd as e ON e.N = s.N – Jafin 2009-06-04 14:29:22

0

它不漂亮...但这里有一些SQL似乎工作。只需将[任务]替换为您的表名。

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 

结果产生下面的结果

[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