Sql server 需要在SQL Server 2008中使用CTC实现业务需求

Sql server 需要在SQL Server 2008中使用CTC实现业务需求,sql-server,Sql Server,为满足以下要求,实现小型SP将非常有帮助 业务规则是: EndDate应为下一个规则的开始日期,否则不应为该规则 视为连续的,并将被视为其他规则系列,如 如下例所示,有两个系列,因为第四个系列 它打破了记录 结果应该是: RuleId Name StartDate EndDate 2 TP1 1/1/2015 00.00.00 3/15/2015 00.00.00 2 TP1 3/18/2015 00.00.00 5/5/

为满足以下要求,实现小型SP将非常有帮助

业务规则是:

EndDate应为下一个规则的开始日期,否则不应为该规则 视为连续的,并将被视为其他规则系列,如 如下例所示,有两个系列,因为第四个系列 它打破了记录

结果应该是:

RuleId  Name    StartDate           EndDate
2       TP1     1/1/2015 00.00.00   3/15/2015 00.00.00
2       TP1     3/18/2015 00.00.00  5/5/2015 00.00.00
根据您的数据和结果,我们可以通过使用月份、行数函数和CTE进行如下操作

对于Sql Server 2012+:

拨弄

对于Sql Server 2008,请使用:

WITH    cte1
          AS ( SELECT   * ,
                        ROW_NUMBER() OVER ( ORDER BY startdate ) rn ,
                        CASE WHEN ( SELECT  MAX(enddate)
                                    FROM    @t ti
                                    WHERE   ti.ruleid = t.ruleid
                                            AND ti.startdate < t.startdate
                                  ) = startdate THEN 0
                             ELSE 1
                        END AS b
               FROM     @t t
             ),
        cte2
          AS ( SELECT   * ,
                        ( SELECT    SUM(b)
                          FROM      cte1 c11
                          WHERE     c11.ruleid = c1.ruleid
                                    AND c11.rn <= c1.rn
                        ) bb
               FROM     cte1 c1
             )
    SELECT  bb ,
            ruleid ,
            name ,
            MIN(startdate) ,
            CASE WHEN COUNT(*) = COUNT(enddate) THEN MAX(enddate)
                 ELSE NULL
            END
    FROM    cte2
    GROUP BY bb ,
            ruleid ,
            name

您使用哪个版本的sql server?谢谢。。Giorgi Nakeuri。我使用的是SQL Server 2008,那里没有超前和滞后功能。您能为SQL Server 2008推荐解决方案吗。请注意,最后一条记录的EndDate值可以为null感谢您的解决方案,我还有一个额外的要求,即最后一条记录的EndDate可以为null,当我使用null而不是“2015年5月5日”时,则不期望结果输出。您能建议所需的更改吗?我无法理解您期望的结果集是什么?您能在您的问题@pardumandhiman中修改该结果吗?如果我使用空规则ID名称StartDate EndDate 2 TP1 1 1/1/2015 00.00.00 1/31/2015 00.00.00 2 TP1 1/31/2015 00.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 3/28/2015 00.00.00 2 TP1 3/28/2015 00.00.00 4/30/2015 00.00.00 2 TP1 4/30/2015 00.00.00.00 5/5/2015 00.00.00.00替换空值而不是最后记录的结束日期,则结果应与RuleId名称StartDate相同EndDate 2 TP1 1/1/2015 00.00.00 3/15/2015 00.00.00 2 TP1 3/18/2015 00.00.00 Null当Sno=2时,则MAX EndDate将其替换为当Sno=2时,则Null感谢您的g8解决方案。我使用的是SQL Server 2008,那里没有Lag和Led功能。您可以分享SQL Server 2008的解决方案吗?您好,我在问题中添加了要求
declare @t table (RuleId  INT, Name  varchar(10),StartDate  datetime,Enddate datetime)

insert into @t (RuleId,Name,StartDate,Enddate)values (

2, 'TP1' ,'1/1/2015' ,'1/31/2015'),

(2, 'TP1', '1/31/2015' ,'2/28/2015'),

(2 ,'TP1', '2/28/2015', '3/15/2015'),

(2, 'TP1', '3/18/2015', '3/28/2015'),

(2, 'TP1', '3/28/2015', '4/30/2015'),

(2, 'TP1', '4/30/2015', '5/5/2015')
;with cte as (
select RuleId,
Name,
Startdate,
enddate,
ROW_NUMBER()OVER(PARTITION BY MONTH(StartDate) ORDER BY MONTH(Enddate))R,
COUNT(*)OVER(PARTITION BY MONTH(ENDDATE) )RR from @t)
,cte2 as 
(
select RuleId,Name,Startdate,enddate,CASE WHEN RR <> R THEN R + 1 ELSE R END CR ,RR,R  from cte 
)
select RuleId,
Name,
CASE WHEN Sno = 1 THEN MIN(StartDate)
 WHEN Sno = 2 then MIN (StartDate) 
       ELSE '' END,
CASE WHEN Sno = 1 THEN MAX(ENDDATE)
 WHEN Sno = 2 then MAX (ENDDATE) 
       ELSE '' END   from ( 
select RuleId,Name,StartDate,Enddate,ROW_NUMBER()OVER(PARTITION BY RR,R ORDER BY CR)Sno from cte2 
where CR = R OR CR = RR ) K
GROUP BY  RuleId,Name,Sno
with cte1 as (select *,
case when lag(enddate) over(partition by ruleid order by startdate) = startdate 
     then 0 else 1 end as b
from t),
cte2 as(select *, sum(b) over(partition by ruleid order by startdate) as s
from cte1)
select ruleid, name, min(startdate), max(enddate) from cte2
group by s, ruleid, name
WITH    cte1
          AS ( SELECT   * ,
                        ROW_NUMBER() OVER ( ORDER BY startdate ) rn ,
                        CASE WHEN ( SELECT  MAX(enddate)
                                    FROM    @t ti
                                    WHERE   ti.ruleid = t.ruleid
                                            AND ti.startdate < t.startdate
                                  ) = startdate THEN 0
                             ELSE 1
                        END AS b
               FROM     @t t
             ),
        cte2
          AS ( SELECT   * ,
                        ( SELECT    SUM(b)
                          FROM      cte1 c11
                          WHERE     c11.ruleid = c1.ruleid
                                    AND c11.rn <= c1.rn
                        ) bb
               FROM     cte1 c1
             )
    SELECT  bb ,
            ruleid ,
            name ,
            MIN(startdate) ,
            CASE WHEN COUNT(*) = COUNT(enddate) THEN MAX(enddate)
                 ELSE NULL
            END
    FROM    cte2
    GROUP BY bb ,
            ruleid ,
            name