Sql server 需要在SQL Server 2008中使用CTC实现业务需求
为满足以下要求,实现小型SP将非常有帮助 业务规则是: EndDate应为下一个规则的开始日期,否则不应为该规则 视为连续的,并将被视为其他规则系列,如 如下例所示,有两个系列,因为第四个系列 它打破了记录 结果应该是: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/
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