跨月的时段如何计算员工的请假天数

禁用F3 2011-11-18 01:05:54

--测试数据
create table #A(员工编号 nvarchar(50) ,日期 datetime, 第一班上班时间 datetime,第一班下班时间 datetime,第二班上班时间 datetime,第二班下班时间 datetime) --班次表
insert into #A values('001','2011-11-01 00:00:00.000','1900-01-01 20:00:00.000','1900-01-01 08:00:00.000',NULL,NULL)
insert into #A values('001','2011-11-02 00:00:00.000','1900-01-01 20:00:00.000','1900-01-01 08:00:00.000',NULL,NULL)
insert into #A values('001','2011-11-03 00:00:00.000','1900-01-01 20:00:00.000','1900-01-01 08:00:00.000',NULL,NULL)
insert into #A values('001','2011-11-04 00:00:00.000','1900-01-01 08:00:00.000','1900-01-01 12:00:00.000','1900-01-01 13:30:00.000','1900-01-01 15:30:00.000')
insert into #A values('001','2011-11-04 00:00:00.000','1900-01-01 08:00:00.000','1900-01-01 12:00:00.000','1900-01-01 13:30:00.000','1900-01-01 15:30:00.000')
insert into #A values('001','2011-11-04 00:00:00.000','1900-01-01 08:00:00.000','1900-01-01 12:00:00.000','1900-01-01 13:30:00.000','1900-01-01 15:30:00.000')

create table #请假表(员工编号 varchar(30),请假起始时间 datetime, 请假结束时间 datetime,请假类别 int,请假小时 decimal(4,2))
insert into #请假表 values('001','2011-10-29 08:00:00.000','2011-11-02 14:00:00.000',1,null)
insert into #请假表 values('001','2011-11-03 13:30:00.000','2011-11-04 14:00:00.000',1,null)
insert into #请假表 values('001','2011-11-29 08:43:00.000','2011-12-03 08:00:00.000',2,null)

算出员工请假类型的请假小时数
/*
想要的结果
员工编号 1 2
------- ------- ------
001 28.5 15.5
*/
...全文
877 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
禁用F3 2011-11-20
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 roy_88 的回复:]
引用 12 楼 chirea 的回复:

引用 10 楼 roy_88 的回复:

'1900-01-01 20:00:00.000','1900-01-01 08:00:00.000'--这是上班12小时,贴出来的结果有误

/*--查出请假时间
员工编号 请假类别 日期 小时
001 1 2011-11-01 00:00:00.000 12.0
001 1 2011-11-0……
[/Quote]
谢谢大版,我算了好久没有算出来.大版你太牛了...
CalvinR 2011-11-20
  • 打赏
  • 举报
回复
大版牛X
中国风 2011-11-20
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 chirea 的回复:]

引用 10 楼 roy_88 的回复:

'1900-01-01 20:00:00.000','1900-01-01 08:00:00.000'--这是上班12小时,贴出来的结果有误

/*--查出请假时间
员工编号 请假类别 日期 小时
001 1 2011-11-01 00:00:00.000 12.0
001 1 2011-11-03 00:00:00.000 12.0
0……
[/Quote]

看到了,是你的数据有问题,在11楼有回复
禁用F3 2011-11-20
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 roy_88 的回复:]

'1900-01-01 20:00:00.000','1900-01-01 08:00:00.000'--这是上班12小时,贴出来的结果有误

/*--查出请假时间
员工编号 请假类别 日期 小时
001 1 2011-11-01 00:00:00.000 12.0
001 1 2011-11-03 00:00:00.000 12.0
001 1 2011-11-04 00:00:0……
[/Quote]
大版,
11月4号在#A表的是8个小时,不是12个小时.上午8点上班12点下班4个小时,下午13:30上班,请假4.5
中国风 2011-11-20
  • 打赏
  • 举报
回复
晕,你的#A表的数据重复了,难怪数据对不上 /*'001','2011-11-04 00:00:00.000'*/

少了这段日期排班
/*
insert into #请假表 values('001','2011-11-29 08:43:00.000','2011-12-03 08:00:00.000',2,null)
*/

结果没计算出/* 15.5 */

参照以下计算方法
set nocount on;
--测试数据
if OBJECT_ID('Tempdb..#A') is not null
drop table #A
go
create table #A(员工编号 nvarchar(50) ,日期 datetime, 第一班上班时间 datetime,第一班下班时间 datetime,第二班上班时间 datetime,第二班下班时间 datetime) --班次表
insert into #A values('001','2011-11-01 00:00:00.000','1900-01-01 20:00:00.000','1900-01-01 08:00:00.000',NULL,NULL)
insert into #A values('001','2011-11-02 00:00:00.000','1900-01-01 20:00:00.000','1900-01-01 08:00:00.000',NULL,NULL)
insert into #A values('001','2011-11-03 00:00:00.000','1900-01-01 20:00:00.000','1900-01-01 08:00:00.000',NULL,NULL)
insert into #A values('001','2011-11-04 00:00:00.000','1900-01-01 08:00:00.000','1900-01-01 12:00:00.000','1900-01-01 13:30:00.000','1900-01-01 15:30:00.000')
--insert into #A values('001','2011-11-04 00:00:00.000','1900-01-01 08:00:00.000','1900-01-01 12:00:00.000','1900-01-01 13:30:00.000','1900-01-01 15:30:00.000')
--insert into #A values('001','2011-11-04 00:00:00.000','1900-01-01 08:00:00.000','1900-01-01 12:00:00.000','1900-01-01 13:30:00.000','1900-01-01 15:30:00.000')
go
if OBJECT_ID('Tempdb..#请假表') is not null
drop table #请假表
go
create table #请假表(员工编号 varchar(30),请假起始时间 datetime, 请假结束时间 datetime,请假类别 int,请假小时 decimal(4,2))
insert into #请假表 values('001','2011-10-29 08:00:00.000','2011-11-02 14:00:00.000',1,null)
insert into #请假表 values('001','2011-11-03 13:30:00.000','2011-11-04 14:00:00.000',1,null)
insert into #请假表 values('001','2011-11-29 08:43:00.000','2011-12-03 08:00:00.000',2,null)

--算出员工请假类型的请假小时数
/*
想要的结果
员工编号 1 2
------- ------- ------
001 28.5 15.5s
*/
declare @dt datetime
set @dt='2011-11-01'

;with b1
as
(
select 员工编号,日期,
第一班上班时间,
第一班下班时间=case when 第一班下班时间<第一班上班时间 then 第一班下班时间+1 else 第一班下班时间 end,
第二班上班时间=case when 第二班上班时间<第一班上班时间 or 第二班上班时间<第一班下班时间 then 第二班上班时间+1 else 第二班上班时间 end,
第二班下班时间=case when 第二班下班时间<第一班上班时间 or 第二班下班时间<第一班下班时间 or 第二班下班时间<第二班上班时间 then 第二班下班时间+1 else 第二班下班时间 end
from #A
where datediff(m,日期,@dt)=0
),b2
as
(
select 员工编号,日期,OnShift=第一班上班时间,offShift=第一班下班时间,ShiftType=1 from b1 --ShiftType用于区分班段,便于查看理解
union all
select 员工编号,日期,OnShift=第二班上班时间,offShift=第二班下班时间,ShiftType=2 from b1 where 第二班上班时间 is not null
)
,b3
as
(
select
a.员工编号,a.日期,b.请假类别,
a.ShiftType,
case when a.日期+a.OnShift>b.请假起始时间 then a.OnShift else b.请假起始时间-a.日期 end as OnShift,
case when a.日期+a.OffShift<b.请假结束时间 then a.OffShift else b.请假结束时间-a.日期 end as OffShift
from b2 as a
inner join #请假表 as b on a.员工编号=b.员工编号
where a.日期+a.offShift>b.请假起始时间 and b.请假结束时间>a.日期+a.OnShift

)
select 员工编号,请假类别,
sum(
DATEDIFF(n,OnShift,OffShift)/60+(DATEDIFF(n,OnShift,OffShift)%60)/30*0.5
) as 小时

from b3
group by 员工编号,请假类别

/*
员工编号 请假类别 小时
001 1 28.5
*/
中国风 2011-11-20
  • 打赏
  • 举报
回复
'1900-01-01 20:00:00.000','1900-01-01 08:00:00.000'--这是上班12小时,贴出来的结果有误

/*--查出请假时间
员工编号 请假类别 日期 小时
001 1 2011-11-01 00:00:00.000 12.0
001 1 2011-11-03 00:00:00.000 12.0
001 1 2011-11-04 00:00:00.000 13.5
*/
Q315054403 2011-11-20
  • 打赏
  • 举报
回复
不奇怪,偶们二十多个班次,各种不同情况都会有。。。有偿支持
QQ348042771 2011-11-20
  • 打赏
  • 举报
回复
datediff
禁用F3 2011-11-19
  • 打赏
  • 举报
回复
请假的计算时间以从当天的上班的开始时与下班的结束时间之内的时间计算,
禁用F3 2011-11-19
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 dawugui 的回复:]

数据怎么算出来的,解释一下.
[/Quote]
001,请假类型等于1的,
11月份请假,他11-01,02,03号的上班时间是晚上20点上班,04号是从白天08点上班,所以他的请假时间是28.5小时.04号的第一班的下班时间是,12:00,第二班的上班时间是13:30,这中间的时间不计算的
这样明白些吗?
dawugui 2011-11-19
  • 打赏
  • 举报
回复
数据怎么算出来的,解释一下.
禁用F3 2011-11-19
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dawugui 的回复:]

看了一下,没看懂,友情 bang ding 了.
[/Quote]
哪没看懂呢?
dawugui 2011-11-19
  • 打赏
  • 举报
回复
看了一下,没看懂,友情 bang ding 了.
AcHerat 元老 2011-11-19
  • 打赏
  • 举报
回复
居然还有夜班!
禁用F3 2011-11-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 acherat 的回复:]

纠结啊!怎么会第一天上班20点,下班8点。。。
[/Quote]
这个20点,如今天的20点上班,明天的8点下班.
dawugui 2011-11-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 acherat 的回复:]
纠结啊!怎么会第一天上班20点,下班8点。。。
[/Quote]夜班的.
AcHerat 元老 2011-11-19
  • 打赏
  • 举报
回复
纠结啊!怎么会第一天上班20点,下班8点。。。

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧