请假时间 请假时间到 请假人员
2015-5-20 2015-5-25 a
2015-5-30 2015-6-1 a
2015-5-24 2015-5-25 b
2015-5-25 2015-6-5 b
2015-4-25 2015-6-5 c
我想要的结果是
a在5月请假天数为:6+2=8天
a在6月请假天数为:1天
b在5月请假天数为:2+7天
b在6月请假天数为:6天
c在4月请假天数为:6天
c在5月请假天数为:31天
c在6月请假天数为:6天
难点就是如果请假时间段不跨月很好统计,但一旦跨月了,请假记录就要撤分开来分别统计单个月的请假天数,
领导要求跨月的就要撤分来统计每月员工的请假天数,
请问怎么来写sql来得到这样的报表?
12 个解决方案
#1
http://bbs.csdn.net/topics/320112058
这篇文章有点跟我的需求差不多,但是也有一点区别,反正就是搞不懂
这篇文章有点跟我的需求差不多,但是也有一点区别,反正就是搞不懂
#2
b在25号重了,就被当成2天处理?
#3
按照这个帖子http://bbs.csdn.net/topics/320112058
我好想快写出来了
回2楼,肯定是2天撒,比如25号到26号,请假天数肯定是2天撒
我好想快写出来了
回2楼,肯定是2天撒,比如25号到26号,请假天数肯定是2天撒
#4
2015-5-24 2015-5-25 b
2015-5-25 2015-6-5 b
这个,25号被算了两次
2015-5-25 2015-6-5 b
这个,25号被算了两次
#5
写错了,不要纠结这个
#6
如果上面的重叠情况,你试下
SELECT 请假人员,MONTH(请假时间)[月份]还有你的一些天数算错了
,SUM(DATEDIFF(DAY,请假时间,请假时间到)+1)[总天数]
FROM(
SELECT 请假人员
,CASE WHEN T2.number=0 THEN T1.请假时间 ELSE DATEADD(MONTH,T2.number,T1.StartDay) END[请假时间]
,CASE WHEN DATEADD(DAY,-1,DATEADD(MONTH,T2.number+1,T1.StartDay))<T1.请假时间到
THEN DATEADD(DAY,-1,DATEADD(MONTH,T2.number+1,T1.StartDay)) ELSE T1.请假时间到 END[请假时间到]
FROM(SELECT 请假时间,请假时间到,请假人员
,DATEADD(DAY,1-DAY(请假时间),请假时间)StartDay
FROM 请假表)T1
JOIN master..spt_values T2 ON T2.number<=DATEDIFF(MONTH,T1.请假时间,T1.请假时间到)
WHERE T2.type='P'
)T
GROUP BY 请假人员,MONTH(请假时间)
ORDER BY 1,2
#7
如果没有上面的重叠情况,你试下
#8
可以加个QQ么,很厉害啊
#9
没用QQ很久了~
#10
;with cte as (
select a.*,DATEDIFF(mm,t1,t2) as mon,b.number,dateadd(dd,-1,dateadd(mm,b.number,dateadd(dd,-day(a.t1)+1,a.t1))) as moe FROM #t a left join master..spt_values b on DATEDIFF(mm,t1,t2)+1>=b.number and b.type='p' and b.number<=12 and b.number>=1
), c as (
select case when mon=0 then DATEDIFF(DD,t1,t2)+1 else
case when number=1 then DATEDIFF(DD,t1,moe)+1 else
case when number=mon+1 then DAY(t2) else
datediff(dd,dateadd(mm,number-1,DATEADD(DD,-DAY(t1)+1,t1)),moe)+1
end
end
end as d,* from cte
)
select m,moe,sum(d) from c group by m,moe order by m,moe
/*
楼主数据有问题,像最后一个6月分,1号到5号只有5天,你写的6天。
m moe
---------- ----------------------- -----------
a 2015-05-31 00:00:00.000 8
a 2015-06-30 00:00:00.000 1
b 2015-05-31 00:00:00.000 9
b 2015-06-30 00:00:00.000 5
c 2015-04-30 00:00:00.000 6
c 2015-05-31 00:00:00.000 31
c 2015-06-30 00:00:00.000 5
*/
#11
我用那个帖子建了个函数也可以实现,但是你的更先进点
谢谢你了
我结贴了你才回 给不了分了,我采用的是6楼的方法
谢谢你了
我结贴了你才回 给不了分了,我采用的是6楼的方法
#12
你们写的是什么数据库的SQL语句啊
#1
http://bbs.csdn.net/topics/320112058
这篇文章有点跟我的需求差不多,但是也有一点区别,反正就是搞不懂
这篇文章有点跟我的需求差不多,但是也有一点区别,反正就是搞不懂
#2
b在25号重了,就被当成2天处理?
#3
按照这个帖子http://bbs.csdn.net/topics/320112058
我好想快写出来了
回2楼,肯定是2天撒,比如25号到26号,请假天数肯定是2天撒
我好想快写出来了
回2楼,肯定是2天撒,比如25号到26号,请假天数肯定是2天撒
#4
2015-5-24 2015-5-25 b
2015-5-25 2015-6-5 b
这个,25号被算了两次
2015-5-25 2015-6-5 b
这个,25号被算了两次
#5
写错了,不要纠结这个
#6
如果上面的重叠情况,你试下
SELECT 请假人员,MONTH(请假时间)[月份]还有你的一些天数算错了
,SUM(DATEDIFF(DAY,请假时间,请假时间到)+1)[总天数]
FROM(
SELECT 请假人员
,CASE WHEN T2.number=0 THEN T1.请假时间 ELSE DATEADD(MONTH,T2.number,T1.StartDay) END[请假时间]
,CASE WHEN DATEADD(DAY,-1,DATEADD(MONTH,T2.number+1,T1.StartDay))<T1.请假时间到
THEN DATEADD(DAY,-1,DATEADD(MONTH,T2.number+1,T1.StartDay)) ELSE T1.请假时间到 END[请假时间到]
FROM(SELECT 请假时间,请假时间到,请假人员
,DATEADD(DAY,1-DAY(请假时间),请假时间)StartDay
FROM 请假表)T1
JOIN master..spt_values T2 ON T2.number<=DATEDIFF(MONTH,T1.请假时间,T1.请假时间到)
WHERE T2.type='P'
)T
GROUP BY 请假人员,MONTH(请假时间)
ORDER BY 1,2
#7
如果没有上面的重叠情况,你试下
#8
可以加个QQ么,很厉害啊
#9
没用QQ很久了~
#10
;with cte as (
select a.*,DATEDIFF(mm,t1,t2) as mon,b.number,dateadd(dd,-1,dateadd(mm,b.number,dateadd(dd,-day(a.t1)+1,a.t1))) as moe FROM #t a left join master..spt_values b on DATEDIFF(mm,t1,t2)+1>=b.number and b.type='p' and b.number<=12 and b.number>=1
), c as (
select case when mon=0 then DATEDIFF(DD,t1,t2)+1 else
case when number=1 then DATEDIFF(DD,t1,moe)+1 else
case when number=mon+1 then DAY(t2) else
datediff(dd,dateadd(mm,number-1,DATEADD(DD,-DAY(t1)+1,t1)),moe)+1
end
end
end as d,* from cte
)
select m,moe,sum(d) from c group by m,moe order by m,moe
/*
楼主数据有问题,像最后一个6月分,1号到5号只有5天,你写的6天。
m moe
---------- ----------------------- -----------
a 2015-05-31 00:00:00.000 8
a 2015-06-30 00:00:00.000 1
b 2015-05-31 00:00:00.000 9
b 2015-06-30 00:00:00.000 5
c 2015-04-30 00:00:00.000 6
c 2015-05-31 00:00:00.000 31
c 2015-06-30 00:00:00.000 5
*/
#11
我用那个帖子建了个函数也可以实现,但是你的更先进点
谢谢你了
我结贴了你才回 给不了分了,我采用的是6楼的方法
谢谢你了
我结贴了你才回 给不了分了,我采用的是6楼的方法
#12
你们写的是什么数据库的SQL语句啊