27,579
社区成员
发帖
与我相关
我的任务
分享
declare @startdate date,@enddate date
set @startdate='2018-01-01'
set @enddate='2018-01-31'
with cte_1
as
(select A.*,dateadd(day,B.number,stime) as in_use
from tb A
join master.dbo.spt_values B on DATEDIFF(DAY,stime,etime)>=number
where type='P'),
cte_2
as
(select *
from (select distinct FJID from tb) as A join
(select DATEADD(DAY,number,@startdate) as schedule,number as seq_1
from master.dbo.spt_values
where type='p' and number<=DATEDIFF(DAY,@startdate,@enddate)) as B on 1=1),
cte_3
as
(select A.*
from cte_2 A
left join (select FJID,
in_use
from cte_1
where in_use between @startdate and @enddate) as B on A.FJID=B.FJID and A.schedule=B.in_use
where B.in_use is null)
select FJID,MIN(schedule) as min_vacant,MAX(schedule) as max_vacant
from
(select *,ROW_NUMBER() over (partition by FJID ORDER BY schedule) as seq_2 from cte_3) as A
group by FJID,seq_1-seq_2
order by FJID,min_vacant
-- 最终指令稍微变形一下
-- 获取 2018-1-28到2018-2-1完全空闲的房间,并获得该房间前一个占用的最后日期和后一个占用的开始日期
select *
from t6 a
cross apply(
select (select max(dt) from t4 where fjid=a.fjid and dt<'2018-1-28') as prov_time
,(select min(dt) from t4 where fjid=a.fjid and dt>'2018-2-1') as next_time
)b
where fjid not in (
select fjid from t5
unpivot(
htid for fjid in ([a-301],[a-302],[a-303],[a-304],[a-305],[a-306],[a-307])
) u
where dt between '2018-1-28' and '2018-2-1'
)
with t as ( -- 原始数据
select '00001' as HTID,'2018-1-2' as stime,'2018-1-8' as etime,'A-301' as FJID
union all select '00002','2018-1-11','2018-2-25','A-301'
union all select '00005','2017-11-2','2018-1-9','A-302'
union all select '00008','2018-1-15','2018-4-8','A-302'
union all select '00009','2018-1-6','2018-1-13','A-302'
union all select '00011','2018-1-6','2018-3-20','A-303'
union all select '00018','2017-11-16','2018-1-28','A-304'
union all select '00019','2018-1-15','2018-1-26','A-306'
union all select '00021','2016-5-10','2019-1-11','A-307'
),t1 as ( -- 转换出已占用日期
select a.*,number,convert(date,dateadd(d,number,stime)) as used_time from t a
cross apply(
select number from master..spt_values where type='p'
and number<=datediff(d,stime,etime)
) b
),t2 as ( -- 获取最小日期和最大日期,以及两日期天数差
select min(used_time) as min_time,max(used_time) as max_time,datediff(d,min(used_time),max(used_time)) as passed from t1
),t3 as ( -- 根据最小日期和天数差获取完整的日期表
select min_time,dateadd(d,number,min_time) as dt
from t2 a
cross apply(
select number from master..spt_values where type='p' and number<=a.passed
) b
),t4 as ( -- 根据日期表和已占用日期转换占用日期表
select dt,htid,fjid from t3 a
left join t1 b
on a.dt=b.used_time
),t5 as ( -- 根据日期表和占用日期表得到房间信息占用情况及每个占用时的合同号,该表已可以作为最终结果使用
select * from t4
pivot(max(htid) for fjid in ([A-301],[A-302],[A-303],[A-304],[A-305],[A-306],[A-307])) p
),t6 as ( -- 房间列表
select 'A-301' as fjid
union all
select 'A-302'
union all
select 'A-303'
union all
select 'A-304'
union all
select 'A-305'
union all
select 'A-306'
union all
select 'A-307'
)
--select * from t5
-- 获取2018-1-1到2018-2-1完全空闲的房间
select * from t6 where fjid not in (
select fjid from t5
unpivot(
htid for fjid in ([a-301],[a-302],[a-303],[a-304],[a-305],[a-306],[a-307])
) u
where dt between '2018-1-1' and '2018-2-1'
)
--order by dt,fjid,htid