日期:2014-05-18  浏览次数:20387 次

高难度SQL语句问题~~100分答谢
有这个一个迷糊的问题我想处理。先把情况说明一下
有表A:里面保存了一些人的请假信息
personcode           starttime           endtime
000001           2007-05-10   13:15:00.000           2007-05-10   16:15:00.000
000002           2007-05-16   08:15:00.000           2007-05-18   13:15:00.000


上面保存的信息就是说,人000001   请了一次假   开始时间和结束时间都有
人000002也请了一次假,一个人当然可以在不同时间请多次假

现在我要统计出,在一个时间范围之内(精确到秒),所有人请假的总时长(秒)
不过这里面要考虑两个问题
1.早上8点上班到下午5点30上班,如果是跨天的记录在这个时间范围内不应该被统计进来。
2.在需要统计的时间范围之内,如果有时间被截断,那么就按统计范围给这个时间截段统计

例如:上述表中人000002的,如果我的统计范围设置成20070516-20070517
那么统计的结果应该是这个人从2007年5月16日早8点15到2007年05月17日晚5点30分的秒数统计,然后再还要排掉晚上5点30到第2天早上8点这段下班时间。

里面涉及到,请假开始时间结束时间,上班时间下班时间,统计范围的开始时间结束时间。我写了一上午,现在头有点晕,谁写个语句参考一下

这个问题还是简化的,因为某日的上班时间和下班时间还需要另一个表计算出来,所以更晕了


------解决方案--------------------
create table #qj(personcode varchar(10),starttime datetime,endtime datetime)
insert #qj select
'000001 ', '2007-05-10 13:15:00.000 ', '2007-05-10 16:15:00.000 ' insert #qj select
'000002 ', '2007-05-16 08:15:00.000 ', '2007-05-18 13:15:00.000 ' insert #qj select
'000001 ', '2007-05-11 13:15:00.000 ', '2007-05-12 16:15:00.000 ' insert #qj select
'000002 ', '2007-05-19 08:15:00.000 ', '2007-05-20 13:15:00.000 '

select personcode,sum(
datediff(ss,
(case when '2007-05-16 '> starttime then '2007-05-16 ' else starttime end),
(case when dateadd(dd,1, '2007-05-19 ') <endtime then dateadd(dd,1, '2007-05-19 ') else endtime end))
-9000*datediff(dd,
(case when '2007-05-16 '> starttime then '2007-05-16 ' else starttime end),
(case when dateadd(dd,1, '2007-05-19 ') <endtime then dateadd(dd,1, '2007-05-19 ') else endtime end))
)秒差
from #qj
where not(starttime> =dateadd(dd,1, '2007-05-19 ') or endtime <= '2007-05-16 ')
group by personcode

personcode 秒差
---------- -----------
000002 220500

(所影响的行数为 1 行)
select datediff(ss, '2007-05-05 05:30:00 ', '2007-05-05 08:00:00 ')--9000
------解决方案--------------------
select datediff(ss, '2007-05-05 05:30:00 ', '2007-05-05 08:00:00 ')--9000
班时间到第2天上班时间这段时间 是9000秒
-9000*datediff(dd,
(case when '2007-05-16 '> starttime then '2007-05-16 ' else starttime end),
(case when dateadd(dd,1, '2007-05-19 ') <endtime then dateadd(dd,1, '2007-05-19 ') else endtime end))
查询时间的开始与记录的开始比较,取最大值,
查询时间的结束与记录的结束比较,取最小值,
它们之间差的天数*每天差的9000秒不是你要的?
------解决方案--------------------
--建立环境,感谢wgzaaa

create table #qj(personcode varchar(10),starttime datetime,endtime datetime)
insert #qj select
'000001 ', '2007-05-10 13:15:00.000 ', '2007-05-10 16:15:00.000 ' insert #qj select
' 000002 ', '2007-05-16 08:15:00.000 ', '2007-05-18 13:15:00.000 ' insert #qj select
'000001 ', '2007-05-11 13:15:00.000 ', '2007-05-12 16:15:00.000 ' insert #qj select
'000002 ', '2007-05-19 08:15:00.000 ', '2007-05-20 13:15:00.000 '


---参数