2012-07-13 44 views
0

请帮我解决这个问题。使用oracle获取范围数据

我有一个包含用户每天检查(checktype = I)和检出(checktype = 0)时间的表,并且我希望每个用户发生的检查总时间大于08:00 AM在特定日期范围内。

我正在使用下面的查询,但只处理每个查询不在一个范围内的一天,所以我必须使用javascript来获取每个用户的延迟量(> 08:00 AM),例如从01/06/2012至06/06/2012

请帮助我在每个用户的时间> 08:00 AM(例如:userid 708)从例如:01/06/2012到06/06/2012在单个查询中。

with tt as 
    ( 
    select TO_DATE('01/06/2012 08:00:00','dd/mm/yyyy hh24:mi:ss') date1 , 
      checktime date2 
    from 
      checkinout 
    where 
      userid = '708' and 
      to_char(checktime,'dd/mm/yyyy') = '01/06/2012' and 
      checktype='I' -- checktype I is check in 
    ) , t2 as 
      ( 
       select numtodsinterval(date2 - date1,'day') dsinterval from tt 
      ) 
      select extract(hour from dsinterval) || ' hours ' || 
        extract(minute from dsinterval) || ' minutes ' || 
        round(extract(second from dsinterval)) || ' seconds' late from t2 

回答

1

我想你想获得多少数小时后(即08:00后)签到已完成:

with t2 as (
select userid 
     ,numtodsinterval(sum(checktime - (trunc(checktime)+8/24)),'day') dsinterval 
     ,count(1) cnt 
    from checkinout 
    where userid='708' 
    and checktime > trunc(checktime)+8/24 
    and trunc(checktime) between to_date('01/06/2012','DD/MM/YYYY') and to_date('06/06/2012','DD/MM/YYYY') 
    and checktype = 'I' 
    group by userid 
) 
select extract(hour from dsinterval) || ' hours ' || 
     extract(minute from dsinterval) || ' minutes ' || 
     round(extract(second from dsinterval)) || ' seconds' late 
     ,cnt 
    from t2; 

请参阅http://sqlfiddle.com/#!4/c4670/11我的测试用例。

编辑:添加栏“cnt”显示多少次

0

考虑在此基础下面的例子中,你可以写你自己的逻辑

WITH tbl AS 
    (SELECT SYSDATE dt 
     FROM DUAL 
     UNION 
     SELECT SYSDATE + (1 + (10/1440)) 
     FROM DUAL 
     UNION 
     SELECT SYSDATE + (2 + (12/1440)) 
     FROM DUAL 
     UNION 
     SELECT SYSDATE + (3 + (13/1440)) 
     FROM DUAL 
     UNION 
     SELECT SYSDATE + (6 + (15/1440)) 
     FROM DUAL 
     UNION 
     SELECT SYSDATE + (8 + (18/1440)) 
     FROM DUAL) 
SELECT EXTRACT (HOUR FROM dsinterval) 
     || ' hours ' 
     || EXTRACT (MINUTE FROM dsinterval) 
     || ' minutes ' 
     || ROUND (EXTRACT (SECOND FROM dsinterval)) 
     || ' seconds' late 
    FROM (SELECT NUMTODSINTERVAL (dt1 - dt2, 'day') dsinterval 
      FROM (SELECT TO_DATE (TO_CHAR (dt, 'DD/MM/YYYY') || ' 08:00:00', 
           'DD/MM/YYYY HH24:MI:SS' 
           ) dt1, 
         TO_DATE (TO_CHAR (dt, 'DD/MM/YYYY HH24:MI:SS'), 
           'DD/MM/YYYY HH24:MI:SS' 
           ) dt2 
        FROM tbl 
       WHERE dt BETWEEN SYSDATE + 2 AND SYSDATE + 5)) 

按照代码,你可以写这样

SELECT EXTRACT (HOUR FROM dsinterval) 
     || ' hours ' 
     || EXTRACT (MINUTE FROM dsinterval) 
     || ' minutes ' 
     || ROUND (EXTRACT (SECOND FROM dsinterval)) 
     || ' seconds' late 
    FROM (SELECT NUMTODSINTERVAL (dt1 - dt2, 'day') dsinterval 
      FROM (SELECT TO_DATE (TO_CHAR (checktime , 'DD/MM/YYYY') || ' 08:00:00', 
           'DD/MM/YYYY HH24:MI:SS' 
           ) dt1, 
         TO_DATE (checktime, 'DD/MM/YYYY HH24:MI:SS') dt2 
        FROM checkinout 
       WHERE checktime BETWEEN start_date AND end_date 
        AND checktype='I'))