首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

[]怎么请假时间段分解生成一天一条记录

2013-10-21 
[求助]如何请假时间段分解生成一天一条记录。原始数据员工ID员工名假别请假开始时间请假结束时间001张三事

[求助]如何请假时间段分解生成一天一条记录。
原始数据

员工ID    员工名    假别    请假开始时间         请假结束时间 
 001       张三     事假     2013-10-16 08:00    2013-10-20 17:20


前提:
1.上班时间是08:00  下班时间是17:20 
2.不需要考虑时间段的假期,每天生成一条记录即可

结果:
员工ID    员工名    假别    请假开始时间         请假结束时间 
 001       张三     事假     2013-10-16 08:00    2013-10-16 17:20
 001       张三     事假     2013-10-17 08:00    2013-10-17 17:20
 001       张三     事假     2013-10-18 08:00    2013-10-18 17:20
 001       张三     事假     2013-10-19 08:00    2013-10-19 17:20
 001       张三     事假     2013-10-20 08:00    2013-10-20 17:20


[解决办法]
spt_values
[解决办法]

create table #tb(员工ID varchar(10),员工名  varchar(10),
假别  varchar(10),请假开始时间 datetime,请假结束时间 datetime)
insert into #tb
values('001','张三','事假','2013-10-16 08:00','2013-10-20 17:20')

select distinct a.员工ID,a.员工名,a.假别, dateadd(day,b.number,a.请假开始时间) as 请假开始时间,
convert(varchar(11),dateadd(day,b.number,a.请假开始时间),120)+convert(varchar(8),a.请假结束时间,108) as 请假结束时间
from #tb a,master..spt_values b
where b.number between 0 and 4

/*
员工ID员工名假别请假开始时间请假结束时间
001张三事假2013-10-16 08:00:00.0002013-10-16 17:20:00
001张三事假2013-10-17 08:00:00.0002013-10-17 17:20:00
001张三事假2013-10-18 08:00:00.0002013-10-18 17:20:00
001张三事假2013-10-19 08:00:00.0002013-10-19 17:20:00
001张三事假2013-10-20 08:00:00.0002013-10-20 17:20:00
*/



[解决办法]

IF OBJECT_ID('tb') IS NOT NULL DROP TABLE tb
CREATE TABLE tb([员工ID] VARCHAR(5),[员工名] NVARCHAR(5),[假别] NVARCHAR(40),[请假开始时间] VARCHAR(16),[请假结束时间] VARCHAR(16))
INSERT INTO tb([员工ID],[员工名],[假别],[请假开始时间],[请假结束时间])
SELECT '001','张三','事假','2013-10-16 08:00','2013-10-20 17:20'

declare @time1 varchar(6),@time2 varchar(6)
set @time1=' 08:00'
set @time2=' 17:20'
select  b.[员工ID],b.[员工名],b.[假别]
,convert(varchar(10),dateadd(dd,a.number,b.[请假开始时间]),120)+@time1 as '请假开始时间'
,convert(varchar(10),dateadd(dd,a.number,b.[请假开始时间]),120)+@time2 as '请假结束时间'
from master..spt_values a with(nolock),tb b with(nolock)
where a.type='P' and a.number>=1 
and a.number<=DATEDIFF(DD,b.[请假开始时间],b.[请假结束时间])


DROP TABLE tb

(1 行受影响)
员工ID  员工名   假别                                       请假开始时间           请假结束时间
----- ----- ---------------------------------------- ---------------- ----------------
001   张三    事假                                       2013-10-17 08:00 2013-10-17 17:20
001   张三    事假                                       2013-10-18 08:00 2013-10-18 17:20
001   张三    事假                                       2013-10-19 08:00 2013-10-19 17:20
001   张三    事假                                       2013-10-20 08:00 2013-10-20 17:20



(4 行受影响)


[解决办法]

create table #tb(员工ID varchar(10),员工名  varchar(10),
假别  varchar(10),请假开始时间 datetime,请假结束时间 datetime)
insert into #tb
select '001','张三','事假','2013-10-16 08:00','2013-10-20 17:20'
union all select '002','李四','事假','2013-10-14 15:30','2013-10-17 17:20'
union all select '003','王五','事假','2013-10-17 08:00','2013-10-19 10:30'

select distinct a.员工ID,a.员工名,a.假别, dateadd(day,b.number,a.请假开始时间) as 请假开始时间,
convert(varchar(11),dateadd(day,b.number,a.请假开始时间),120)+convert(varchar(8),a.请假结束时间,108) as 请假结束时间
from #tb a
left join master..spt_values b
on b.number between 0 and DATEDIFF(day,请假开始时间,请假结束时间)
order by a.员工ID,4

/*
员工ID员工名假别请假开始时间请假结束时间
001张三事假2013-10-16 08:00:00.0002013-10-16 17:20:00
001张三事假2013-10-17 08:00:00.0002013-10-17 17:20:00
001张三事假2013-10-18 08:00:00.0002013-10-18 17:20:00
001张三事假2013-10-19 08:00:00.0002013-10-19 17:20:00
001张三事假2013-10-20 08:00:00.0002013-10-20 17:20:00
002李四事假2013-10-14 15:30:00.0002013-10-14 17:20:00
002李四事假2013-10-15 15:30:00.0002013-10-15 17:20:00
002李四事假2013-10-16 15:30:00.0002013-10-16 17:20:00
002李四事假2013-10-17 15:30:00.0002013-10-17 17:20:00
003王五事假2013-10-17 08:00:00.0002013-10-17 10:30:00
003王五事假2013-10-18 08:00:00.0002013-10-18 10:30:00
003王五事假2013-10-19 08:00:00.0002013-10-19 10:30:00
*/

[解决办法]

create table #tb(员工ID varchar(10),员工名  varchar(10),    假别  varchar(10),请假开始时间 datetime,请假结束时间 datetime)
insert into #tb values('001','张三','事假','2013-10-16 08:00','2013-10-20 17:20')

select 员工ID,员工名,假别,DATEADD(day,d.number-1,请假开始时间),DATEADD(day,(d.number-(datediff(DAY,请假开始时间,请假结束时间)+1)),请假结束时间) 
from #tb c
right join
(
select number from (
select ((datediff(DAY,请假开始时间,请假结束时间))+1) as 'qday' from #tb) a
left join 
(
select (number+1)as number from  master.dbo.spt_values where status=0 and type='p') b
on number<=qday) d 
on d.number<>0

[解决办法]
引用:
Quote: 引用:

修改了一下,刚才少了数据了:



--drop table tb

create table tb(
员工ID varchar(10),    
员工名 varchar(20),   
假别   varchar(10),
请假开始时间 datetime,         
请假结束时间 datetime
)

insert into tb
select '001','张三','事假','2013-10-16 08:00','2013-10-20 17:20' union all
select '002','李四','事假','2013-10-14 15:30','2013-10-17 17:20' union all
select '003','王五','事假','2013-10-17 08:00','2013-10-19 10:30'


select datediff(day,请假开始时间,请假结束时间)
from tb


--用递归来生成序列
;with t
as
(
select 0 as number
union all
select number + 1 as number
from t
where t.number < 1000
)

select tb.员工ID,
       tb.员工名,
       tb.假别,
       
       --请假时间在下午,时间在'13:30' and '17:20',请假时间在上午,那么时间在'08:00' and '12:30'
       case when convert(varchar(5),tb.请假开始时间,114) between '13:30' and '17:20'
                 then convert(varchar(11),dateadd(day,t.number,tb.请假开始时间),120)+'13:30' 
                 
            when convert(varchar(5),tb.请假结束时间,114) between '08:00' and '12:30'
                 then convert(varchar(11),dateadd(day,t.number,tb.请假开始时间),120)+'08:30'
            
            else convert(varchar(11),dateadd(day,t.number,tb.请假开始时间),120)+'08:30'
       end as 请假开始时间,
       
       case when convert(varchar(5),tb.请假开始时间,114) between '13:30' and '17:20'
                 then convert(varchar(11),dateadd(day,t.number,tb.请假开始时间),120)+'17:20' 
                 
            when convert(varchar(5),tb.请假结束时间,114) between '08:00' and '12:30'


                 then convert(varchar(11),dateadd(day,t.number,tb.请假开始时间),120)+'12:30'
            
            else convert(varchar(11),dateadd(day,t.number,tb.请假开始时间),120)+'17:20'
       end as 请假结束时间          
from tb
inner join  t
        on datediff(day,请假开始时间,请假结束时间) >= t.number
order by 员工ID,请假开始时间
option(maxrecursion 1000)           

/*员工ID       员工名                  假别         请假开始时间           请假结束时间
---------- -------------------- ---------- ---------------- ----------------
001        张三                   事假         2013-10-16 08:30 2013-10-16 17:20
001        张三                   事假         2013-10-17 08:30 2013-10-17 17:20
001        张三                   事假         2013-10-18 08:30 2013-10-18 17:20
001        张三                   事假         2013-10-19 08:30 2013-10-19 17:20
001        张三                   事假         2013-10-20 08:30 2013-10-20 17:20
002        李四                   事假         2013-10-14 13:30 2013-10-14 17:20
002        李四                   事假         2013-10-15 13:30 2013-10-15 17:20
002        李四                   事假         2013-10-16 13:30 2013-10-16 17:20
002        李四                   事假         2013-10-17 13:30 2013-10-17 17:20
003        王五                   事假         2013-10-17 08:30 2013-10-17 12:30
003        王五                   事假         2013-10-18 08:30 2013-10-18 12:30
003        王五                   事假         2013-10-19 08:30 2013-10-19 12:30

(12 行受影响)
*/


感谢yupeigu的回复,
但结果不是这个,应该是:
员工ID       员工名                  假别         请假开始时间           请假结束时间
---------- -------------------- ---------- ---------------- ----------------
001        张三                   事假         2013-10-16 08:00 2013-10-16 17:20
001        张三                   事假         2013-10-17 08:00 2013-10-17 17:20
001        张三                   事假         2013-10-18 08:00 2013-10-18 17:20
001        张三                   事假         2013-10-19 08:00 2013-10-19 17:20


001        张三                   事假         2013-10-20 08:00 2013-10-20 17:20
002        李四                   事假         2013-10-14 13:30 2013-10-14 17:20
002        李四                   事假         2013-10-15 08:00 2013-10-15 17:20
002        李四                   事假         2013-10-16 08:00 2013-10-16 17:20
002        李四                   事假         2013-10-17 08:00 2013-10-17 17:20
003        王五                   事假         2013-10-17 08:00 2013-10-17 17:20
003        王五                   事假         2013-10-18 08:00 2013-10-18 17:20
003        王五                   事假         2013-10-19 08:00 2013-10-19 12:30




我修改了一下,是这样的不:

--drop table tb

create table tb(
员工ID varchar(10),    
员工名 varchar(20),   
假别   varchar(10),
请假开始时间 datetime,         
请假结束时间 datetime
)

insert into tb
select '001','张三','事假','2013-10-16 08:00','2013-10-20 17:20' union all
select '002','李四','事假','2013-10-14 15:30','2013-10-17 17:20' union all
select '003','王五','事假','2013-10-17 08:00','2013-10-19 10:30'




--用递归来生成序列
;with t
as
(
select 0 as number
union all
select number + 1 as number
from t
where t.number < 1000
)

select tb.员工ID,
       tb.员工名,
       tb.假别,
       
       --请假时间在下午,时间在'13:30' and '17:20',请假时间在上午,那么时间在'08:00' and '12:30'
       case when convert(varchar(5),tb.请假开始时间,114) between '13:30' and '17:20'
                 and t.number = 0
                 then convert(varchar(11),dateadd(day,t.number,tb.请假开始时间),120)+'13:30' 
                 
            when convert(varchar(5),tb.请假结束时间,114) between '08:00' and '12:30'
                 then convert(varchar(11),dateadd(day,t.number,tb.请假开始时间),120)+'08:30'
            
            else convert(varchar(11),dateadd(day,t.number,tb.请假开始时间),120)+'08:30'
       end as 请假开始时间,
       
       case when convert(varchar(5),tb.请假开始时间,114) between '13:30' and '17:20'
                 then convert(varchar(11),dateadd(day,t.number,tb.请假开始时间),120)+'17:20' 
                 
            when convert(varchar(5),tb.请假结束时间,114) between '08:00' and '12:30'
                 and t.number = datediff(day,请假开始时间,请假结束时间)
                 then convert(varchar(11),dateadd(day,t.number,tb.请假开始时间),120)+'12:30'
            
            else convert(varchar(11),dateadd(day,t.number,tb.请假开始时间),120)+'17:20'
       end as 请假结束时间          


from tb
inner join  t
        on datediff(day,请假开始时间,请假结束时间) >= t.number
order by 员工ID,请假开始时间
option(maxrecursion 1000)           

/*
员工ID       员工名                  假别         请假开始时间           请假结束时间
---------- -------------------- ---------- ---------------- ----------------
001        张三                   事假         2013-10-16 08:30 2013-10-16 17:20
001        张三                   事假         2013-10-17 08:30 2013-10-17 17:20
001        张三                   事假         2013-10-18 08:30 2013-10-18 17:20
001        张三                   事假         2013-10-19 08:30 2013-10-19 17:20
001        张三                   事假         2013-10-20 08:30 2013-10-20 17:20
002        李四                   事假         2013-10-14 13:30 2013-10-14 17:20
002        李四                   事假         2013-10-15 08:30 2013-10-15 17:20
002        李四                   事假         2013-10-16 08:30 2013-10-16 17:20
002        李四                   事假         2013-10-17 08:30 2013-10-17 17:20
003        王五                   事假         2013-10-17 08:30 2013-10-17 17:20
003        王五                   事假         2013-10-18 08:30 2013-10-18 17:20
003        王五                   事假         2013-10-19 08:30 2013-10-19 12:30

(12 行受影响)
*/

热点排行