使用oracle获取范围内的数据

时间:2012-07-13 03:39:10

标签: sql oracle

请帮我解决这个问题。

我有一个包含用户签入的表(checktype = I)并且每天检查(checktype = 0)时间,并且我希望得到每个用户的检查总时间>上午08:00在特定日期范围内。

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

请帮助我获取金额(计数)检查时间>每个用户08:00 AM(例如:用户ID 708)从ex: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

2 个答案:

答案 0 :(得分: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”以显示多少次

答案 1 :(得分: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'))