日期:2014-05-16  浏览次数:20973 次

求一条 sql语句 急急!
现在有个table ,工人开工记录表,其中记录了开工人worker,开工时间 begtime,结束时间endtime等信息
  字段如下: worker(int),begtime(date),endtime(date)(其实不止这些字段)
现在需求如下:
我要根据开工时间来查找某人的上班时间:
本来需求是工人只要在当天有开工记录的话,他的上班工时都算为8H,
比如工人a的开工时间段在09-08-01到09-08-17上班工时,(注:一天会有多条开工记录)
比如:
worker1 , 2009-08-01 02:34:11,2009-08-01 04:34:11
worker1 , 2009-08-01 02:44:11,2009-08-01 04:57:11
......
  
sql如下:
select count(*) * 8 'H' from(
  select distinct to_char(begtime,'yyyy-dd-dd') from tablename
where t.worker = 'worker1'
and t.begdate between to_date('09-08-01 'yyyy-mm-dd hh24:mi:ss') an to_date('09-08-17 23: 59:00 'yyyy-mm-dd hh24:mi:ss');
)
这样就求出上班的工时为 resultSet.getInt('H');
现在出现了这种情况:
有的员工上夜班22:00到第二天06:00)此时他的开工时间应该算8H
此时他的工作时段跨越两天,如果他在 00:00之前有开工记录和 00:00之后有开记录
比如他的开工时间为当天22:30 和第二天的 01:10
 用上面的语句查询的话上班时间就会多算8个小时(16H),(因为有两天,count(*)=2)但是应该只算他的上班时间为8H,只是他上班跨越了两天.
所以现在我要的语句是:
 如果工人在当天早上08:00到23:59有开工记录的算8H,第二天00:00到06:00还有开工记录的不再计算,
但是如果当天08:00到23:59没有记录,但是当天00:00到06点有开工记录也算8H,
如果工人在早上08:00到23:59分开工的算上班工时为8

(其实对于上夜班的人(22:00 - 06:00)来说就是当天22:00-00:00有开工记录(算8H),但是如果次日00:00-06:00还有开工记录的不再算,当如果22:00-00:00没有开工,00:00-06:00有开工记录酸8H)
请问这样的语句该怎么来写呢谢谢!




------解决方案--------------------
SQL code
select sum(8) H 
from  (select to_date('2009-08-01','yyyy-mm-dd')-1 + rownum days from dual 
       connect by rownum <=to_date('2009-08-17','yyyy-mm-dd')-to_date('2009-08-01','yyyy-mm-dd')+1
      ) t1 
where exists (select 1 from tablename t 
              where (t.begdate between to_date(to_char(t1.days,'yyyy-mm-dd')||' 08:00:01','yyyy-mm-dd hh24:mi:ss')
                               and     to_date(to_char(t1.days,'yyyy-mm-dd')||' 22:00:00','yyyy-mm-dd hh24:mi:ss')
                    )
              OR    (t.begdate between to_date(to_char(t1.days,'yyyy-mm-dd')||' 22:00:01','yyyy-mm-dd hh24:mi:ss')
                               and     to_date(to_char(t1.days+1,'yyyy-mm-dd')||' 06:00:00','yyyy-mm-dd hh24:mi:ss')
                    )
             );

------解决方案--------------------
SQL code
select sum(8) H 
from  (select to_date('2009-08-01','yyyy-mm-dd')-1 + rownum days from dual 
       connect by rownum <=to_date('2009-08-17','yyyy-mm-dd')-to_date('2009-08-01','yyyy-mm-dd')+1
      ) t1 
where exists (select 1 from tablename t 
              where ((t.begdate between to_date(to_char(t1.days,'yyyy-mm-dd')||' 08:00:01','yyyy-mm-dd hh24:mi:ss')
                               and     to_date(to_char(t1.days,'yyyy-mm-dd')||' 22:00:00','yyyy-mm-dd hh24:mi:ss')
                     )
              OR     (t.begdate between to_date(to_char(t1.days,'yyyy-mm-dd')||' 22:00:01','yyyy-mm-dd hh24:mi:ss')
                               and     to_date(to_char(t1.days+1,'yyyy-mm-dd')||' 06:00:00','yyyy-mm-dd hh24:mi:ss')
                    ))
              AND     t.worker = 'worker1'
             );