0

これを解決するのを手伝ってください。

ユーザーのチェックイン (checktype = I) とチェックアウト (checktype = 0) の時間を毎日含むテーブルがあり、特定の午前 08:00 を超えるユーザーごとのチェックイン時間の合計を取得したいと考えています。日付範囲。

以下のクエリを使用していますが、範囲外のクエリごとに 1 日しか処理しないため、JavaScript を使用してループし、ユーザーごとの遅延 (> 08:00 AM) を取得する必要があります (たとえば、2012 年 1 月 6 日から 2012 年 1 月 6 日まで)。 2012/06/06

単一のクエリで、ex:01/06/2012 から 06/06/2012 までのユーザー (例: userid 708) ごとの 08:00 AM を超える金額 (カウント) チェックイン時間を取得するのを手伝ってください。

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 に答える