日期:2014-05-17  浏览次数:20391 次

宿舍流转表 查某段时间内,人员及入住天数
本帖最后由 zxlkrz21 于 2013-04-27 20:13:59 编辑
宿舍管理

有如下流转表

人员 时间 类型

A 2000-1-1 入住

A 2000-1-15 退出

A 2000-1-19 入住

A 2000-1-26 退出

B 2000-1-1 入住

C 2000-1-1 入住

C 2000-1-2 退出

D 2000-1-10 入住

想根据此表 查出 2000-1-5 到 2000-1-25 有哪些人 住了几天

人员 天数
A 16
B 20
D 15

希望能考虑效率,非常感谢
因为感觉自己写的效率应该不咋地

------解决方案--------------------
if OBJECT_ID('t') is not null drop table t;
create table t
(
name varchar(20),
mtime datetime,
type varchar(10)
)

insert into t
select 'A','2000-1-1','入住' union
select 'A','2000-1-15','退出' union
select 'A','2000-1-19','入住' union
select 'A','2000-1-26','退出' union
select 'B','2000-1-1','入住' union
select 'C','2000-1-1','入住' union
select 'C','2000-1-2','退出' union
select 'D','2000-1-10','入住'

declare @startTime datetime,@endTime datetime;
set @startTime='2000-1-5'
set @endTime='2000-1-25';
with cte
as
(
select t1.name, t1.mtime 注入时间
,case 
when min(t2.mtime) is not null  
then (case when(min(t2.mtime)>=@endTime) then @endTime else min(t2.mtime)end)
else @endTime end 退出时间
from
(select * from t where t.type='入住' and t.mtime<@endTime) t1 
left join 
(select * from t where t.type='退出') t2 
on t1.name=t2.name   and t1.mtime<t2.mtime
group by t1.name,t1.mtime
)
select cte.name
,SUM(DATEDIFF(dd
  ,(case when cte.注入时间<@startTime then @startTime else cte.注入时间 end)
  ,(case when cte.退出时间>@endTime then @endTime else cte.退出时间 end))) 时间
from
cte
where cte.退出时间>=@startTime
group by cte.name 

------解决方案--------------------

create table 流转表(人员 varchar(5), 时间 date, 类型 varchar(10))

insert into 流转表
select 'A', '2000-1-1', '入住' union all
select 'A', '2000-1-15', '退出' union all
select 'A', '2000-1-19', '入住' union all
select 'A', '2000-1-26', '退出' union all
select 'B', '2000-1-1', '入住' union all
select 'C', '2000-1-1', '入住' union all
select 'C', '2000-1-2', '退出' union all
select 'D', '2000-1-10', '入住'


declare @begindate as date,@enddate as date
select @begindate='2000-1-5',@enddate='2000-1-25'

select 人员,sum(ds) '天数'
from(
select a.人员,
       case when a.时间>@enddate or b.时间<@begindate then 0
            when a.时间<=@begindate and isnull(b.时间,@enddate)<=