Sql server 分层数据所需的cte实现

Sql server 分层数据所需的cte实现,sql-server,sql-server-2008,Sql Server,Sql Server 2008,仅查找SQL Server 2008的优化代码(因为SQL Server 2008中不提供Lag和Lead函数)。用于以下要求。(最后记录结束日期可以为空或不为空) 业务规则是: 结束日期应为下一个规则的开始日期,否则规则不应被认为是连续的,并将被处理为其他规则系列,如下面的示例所示,有三个系列,因为第四条记录和7条记录规则已经被制动。 RuleId Name StartDate EndDate ------------------------------------

仅查找SQL Server 2008的优化代码(因为SQL Server 2008中不提供
Lag
Lead
函数)。用于以下要求。(最后记录结束日期可以为空或不为空)

业务规则是:

结束日期应为下一个规则的开始日期,否则规则不应被认为是连续的,并将被处理为其他规则系列,如下面的示例所示,有三个系列,因为第四条记录和7条记录规则已经被制动。

RuleId  Name    StartDate           EndDate
-----------------------------------------------------------    
2       TP1     1/1/2015 00.00.00   1/31/2015 00.00.00
2       TP1     1/31/2015 00.00.00  2/28/2015 00.00.00
2       TP1     2/28/2015 00.00.00  3/15/2015 00.00.00
2       TP1     3/18/2015 00.00.00  11/28/2015 00.00.00
2       TP1     11/28/2015 00.00.00 4/30/2016 00.00.00
2       TP1     4/30/2016 00.00.00  10/5/2016 00.00.00
2       TP1     10/25/2016 00.00.00  11/15/2016 00.00.00
2       TP1     11/15/2016 00.00.00  Null
结果如下

2       TP1     1/1/2015 00.00.00  3/15/2015 00.00.00
2       TP1     3/18/2015 00.00.00 10/5/2016 00.00.00
2       TP1     10/25/2016 00.00.00  Null

您可以使用
分区执行
行编号()
,然后使用rn=rn+1执行自联接,并执行
DATEDIFF
,根据它可以对结果进行分组

试试这样的

DECLARE @Rules TABLE(RuleId  INT,Name CHAR(3),    StartDate DATE,           EndDate DATE)

INSERT INTO @Rules VALUES
(3 ,'TP3', '3/18/2015', '11/28/2015'),
(3 ,'TP3', '11/28/2015', '4/30/2016'),
(3 ,'TP3', '4/30/2016', '10/5/2016'),
(3 ,'TP3', '10/25/2016', '11/15/2016'),
(3 ,'TP3', '11/15/2016', null) 


;WITH CTE AS 
(
SELECT ROW_NUMBER() OVER(PARTITION BY RuleID ORDER BY StartDate) rn,*
FROM @Rules
), CTE2 AS
(
SELECT ISNULL(DATEDIFF(day,C1.EndDate,C2.StartDate),0) diff,C1.*
FROM CTE C1 
LEFT JOIN CTE C2 ON C1.rn + 1 = C2.rn
 AND C1.RuleId = C2.RuleId
)
SELECT RuleId,Name,MIN(StartDate)  StartDate,NULLIF(MAX(CASE WHEN EndDate IS NULL THEN '2999/12/31' ELSE EndDate END),'2999/12/31') EndDate
FROM
(
SELECT C2.Diff,C1.RuleId,C1.Name,C1.StartDate,C1.EndDate
FROM CTE2 C1
CROSS APPLY (SELECT ISNULL(SUM(Diff),0) Diff FROM CTE2 C2 WHERE C1.StartDate > C2.StartDate AND C1.RuleId = C2.RuleId) C2
) C
GROUP BY RuleId,Name,Diff
ORDER BY RuleId,Diff

感谢g8的解决方案,但是当我尝试对以下数据范围进行相同的测试时,没有考虑第一条记录(3、'TP3'、'2015年3月18日'、'2015年11月28日'、(3、'TP3'、'2015年11月28日'、'2016年4月30日')、(3、'TP3'、'2016年4月30日'、'2016年10月5日')、(3、'TP3、'TP3、'2016年10月25日'、'2016年11月15日),(3,'TP3','11/15/2016',null)不应为结果开始日期检查更新的答案