0

入力テーブル:

store    | employee  | date             |  timein  | timeout |   
    1    |      A    |        1-jan-12  |  10:00   | 17:00   |
    1    |      A    |        1-jan-12  |  20:00   | 22:00   |
    2    |      B    |        1-jan-12  |  10:00   |  -      |
    2    |      B    |        1-jan-12  |  17:00   | 20:00   |
    2    |      B    |        2-jan-12  |  10:00   | 17:00   |
    3    |      C    |        1-jan-12  |  10:00   | 12:00   |
    3    |      C    |        1-jan-12  |  13:00   | 15:00   |
    3    |      C    |        1-jan-12  |  20:00   | 23:00   |

必要な出力:

store | employee | date      |  timein  | timeout | hours | working_days |
 1    |     A    | 1-jan-12  |  10:00   | 17:00   |   7   |              |
 1    |     A    | 1-jan-12  |  20:00   | 22:00   |   2   |        1     |
 2    |     B    | 1-jan-12  |  10:00   |  -      |   0   |              | 
 2    |     B    | 1-jan-12  |  17:00   | 20:00   |   5   |        0     | 
 2    |     B    | 2-jan-12  |  10:00   | 17:00   |   7   |        1     | 
 3    |     C    | 1-jan-12  |  10:00   | 12:00   |   2   |              | 
 3    |     C    | 1-jan-12  |  13:00   | 15:00   |   2   |              | 
 3    |     C    | 1-jan-12  |  20:00   | 23:00   |   3   |        1     |

私の質問は:

select 
      store, 
      employee,
      date,
      timein,
      timeout,
      cast(trim(trailing ':' from cast(timeout) as number)-trim(trailing ':' from cast(timein) as number) as number) as hours,
     case
      when timeout is null then 0 and
     end
from
      tableattend
where date between '1-jan-12' and '2-jan-12' and store between 'A' and 'C'

working_daysフィールドはこのように表示されますが、上記のような結果を作成するための正確な関数を取得できませんでした。案内してください。

4

3 に答える 3

0

私は就業日のルールを少し異なって解釈したため、APCの回答にわずかな違いがあります...これにより、期待される出力が得られます。しかし、あなたが述べたルールと一致していないようです:

select store, employee, dt, timein, timeout, hours,
    case when rn = 1 then decode(tmp_timeout, null, 0, 1) end as working_days
from (
    select store, employee, dt, timein, timeout,
          case when timeout is null then 0
          else extract (hour from to_dsinterval('0 ' || timeout || ':00')
              - to_dsinterval('0 ' || timein || ':00'))
          end as hours,
          first_value(timeout)
              over (partition by store, employee, dt
                  order by timeout nulls first) as tmp_timeout,
          row_number()
              over (partition by store, employee, dt
                  order by timein desc) as rn
    from tableattend
)
where dt between '1-jan-12' and '2-jan-12'
-- and store between 'A' and 'C' -- store is numeric??
/

dt予約語を避けるために日付列を呼び出しましたが、それ以外の場合は、指定したものと一致させようとしました。

     STORE EMPLOYEE DT        TIMEIN TIMEOUT      HOURS WORKING_DAYS
---------- -------- --------- ------ ------- ---------- ------------
         1 A        01-JAN-12 10:00  17:00            7              
         1 A        01-JAN-12 20:00  22:00            2            1 
         2 B        01-JAN-12 10:00                   0              
         2 B        01-JAN-12 17:00  20:00            3            0 
         2 B        02-JAN-12 10:00  17:00            7            1 
         3 C        01-JAN-12 10:00  12:00            2              
         3 C        01-JAN-12 13:00  15:00            2              
         3 C        01-JAN-12 20:00  23:00            3            1 

個別の (varchar2) 列としてではなく、完全な日付として出入りする時間を格納する場合、これは簡単になります。誰かが真夜中を過ぎて働いた場合に何が起こるか、または起こるべきかは明確ではないため、timeoutは の前に表示されますtimein

于 2013-03-07T10:04:21.207 に答える
0

上記の例のように、時間部分を減算して時間のみを取得する方法のいくつかの例。営業日を取得する方法が明確ではありません。労働時間を 8 で割って労働日を取得できると思います... すべての例がテストされています。

SELECT round((time_diff/3600)/24, 1) days
     , trunc(time_diff/3600) hrs
     , trunc(mod(time_diff, 3600) / 60) mnt
     , trunc(mod(time_diff, 3600) / 60 /60) sec
  FROM
  (
   SELECT time_in, time_out, (time_out-time_in)* 86400 time_diff
     FROM 
   (
    SELECT to_date('01-JAN-2012 17:00:00', 'DD-MON-YYYY HH24:MI:SS') time_out
         , to_date('01-JAN-2012 10:00:00', 'DD-MON-YYYY HH24:MI:SS') time_in
      FROM dual
   ))
   /

Extract の使用例:

 Select time_in, time_out, time_diff,
        EXTRACT(DAY FROM time_diff) days,
        EXTRACT(HOUR FROM time_diff) hours,
        EXTRACT(MINUTE FROM time_diff) minutes,
        EXTRACT(SECOND FROM time_diff) seconds
   From
   (
    Select time_in, time_out, (time_out - time_in) time_diff
      From
     (
      Select CAST(to_date('01-JAN-2012 17:00:00', 'DD-MON-YYYY HH24:MI:SS') AS TIMESTAMP) time_out
           , CAST(to_date('01-JAN-2012 10:00:00', 'DD-MON-YYYY HH24:MI:SS') AS TIMESTAMP) time_in
         From dual
    ))
  /
于 2013-03-07T15:52:20.213 に答える
0

WORKING_DAYS を生成するためのルールは次のとおりです。

  • レコードが DATE の最後のレコードでない場合はNULL
  • レコードが DATE の最後のレコードであるが、TIMEOUT が null の場合は0
  • そうでなければ1

これは、特定の問題に対処するクエリの簡略版です。

select date
       , timein 
       , timeout
       , case 
            when rn != 1 then null
            when timeout is null then 0
            else 1
          end as working_days
from ( select date
              , timein 
              , timeout
              , row_number() over partition by date order by timein desc ) rn
       from  tableattend
      where date between '1-jan-12' and '2-jan-12' 
      and store between 'A' and 'C' )
order by date, timein
于 2013-03-07T09:31:23.073 に答える