Sql server SQL折叠顺序时间序列集
在MSSQL中,我有一组具有开始和结束时间的任务 我想做的是将顺序任务折叠在一起。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
所以我对顺序的定义是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