我正在使用SQL Server 2008 R2并拥有下表。
CREATE TABLE room
(id int,
dt date,
course char(1),
constraint pk_roomtime primary key (id, dt)
);
INSERT INTO room (id, dt, course) values
(1, '20140412', 'A'),
(1, '20140414', 'A'),
(1, '20140415', 'A'),
(1, '20140416', 'B'),
(1, '20140417', 'A'),
(1, '20140421', 'A'),
(1, '20140422', 'B'),
(1, '20140423', 'B');
我必须找到一个房间里每个课程的第一个和最后一个日期,而不考虑日期之间的差距。我对房间1的结果应如下所示:
A 20140412 20140415
B 20140416 20140416
A 20140417 20140421
B 20140422 20140423
我尝试使用联接到日历表但无法使其工作。
答案 0 :(得分:1)
仅仅为了完整起见,回答@Nico评论中提出的问题,这是2012年的解决方案(我知道OP使用的是2008r2):
with x as (
select *,
lag(dt) over(order by dt) as lag_dt,
lag(course) over(order by dt) as lag_course
from room
),
y as (
select *,
sum(case when course<>lag_course then 1 else 0 end) over(order by dt) as grp
from x
)
select min(course), min(dt), max(dt)
from y
group by grp
答案 1 :(得分:0)
不完全是您要求的结果集,但我认为结果本身符合您的想法:
with "cte" as
(
select
rn = row_number() over ( order by dt )
, *
from room
)
,"preprocessed" as
(
select
"current"."course"
, startDate = case when "predecessor"."id" is null then "current"."dt" else null end
, endDate = case when "successor"."id" is null then "current"."dt" else null end
, "current"."dt"
from
"cte" as "current"
left join "cte" as predecessor
on 1 = 1
and "current"."id" = predecessor."id"
and "current"."course" = predecessor."course"
and "current"."rn" -1 = predecessor."rn"
left join "cte" as successor
on 1 = 1
and "current"."id" = successor."id"
and "current"."course" = successor."course"
and "current"."rn" +1 = successor."rn"
), "pvt" as
(
select
"course"
, "dt"
, "type"
from
( select "course", "startDate", "endDate" from "preprocessed" ) as data
unpivot ( "dt" for "type" in ( "startDate", "endDate")) as pvt
)
select * from
"pvt"