For Sql Server 2012+
:
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
Fiddle http://sqlfiddle.com/#!6/aadf4/1 http://sqlfiddle.com/#!6/aadf4/1
对于 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