在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特定功能。
答案 0 :(得分: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”。
答案 1 :(得分: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
答案 2 :(得分:0)