0

请帮我解决这个问题。

我有一个表,其中包含用户每天签入(checktype = I)和签出(checktype = 0)的时间,我想获得每个用户在特定时间 > 08:00 AM 的签入时间总量日期范围。

我正在使用下面的查询,但每个查询只处理一天,不在一个范围内,所以我必须使用 javascript 循环获取每个用户的延迟量(> 08:00 AM),例如从 2012 年 1 月 6 日到2012 年 6 月 6 日

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

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
4

2 回答 2

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”以显示多少次

于 2012-07-13T05:56:30.150 回答
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'))
于 2012-07-13T05:40:45.960 回答