sql >> データベース >  >> RDS >> Oracle

シフトを使用してSQLの時間差を計算する

    再帰的なサブクエリ因数分解句を使用して、時間範囲内の毎日を生成し、それをシフトと相関させて、毎日の時間をシフト時間内に制限し、集計して合計を取得します。

    Oracle18セットアップ

    CREATE TABLE times ( start_date, End_Date ) AS
    SELECT DATE '2017-02-21' + INTERVAL '07:52:32' HOUR TO SECOND,
           DATE '2017-02-22' + INTERVAL '09:56:32' HOUR TO SECOND
    FROM   DUAL
    UNION ALL
    SELECT DATE '2017-02-21' + INTERVAL '09:52:32' HOUR TO SECOND,
           DATE '2017-02-23' + INTERVAL '17:52:32' HOUR TO SECOND
    FROM   DUAL;
    
    CREATE TABLE weekly_shifts ( shift_day, Start_Time, End_Time ) AS
    SELECT 'MON', INTERVAL '09:00' HOUR TO MINUTE, INTERVAL '18:00' HOUR TO MINUTE FROM DUAL UNION ALL
    SELECT 'TUE', INTERVAL '10:00' HOUR TO MINUTE, INTERVAL '19:00' HOUR TO MINUTE FROM DUAL UNION ALL
    SELECT 'WED', INTERVAL '09:00' HOUR TO MINUTE, INTERVAL '18:00' HOUR TO MINUTE FROM DUAL UNION ALL
    SELECT 'THU', INTERVAL '10:00' HOUR TO MINUTE, INTERVAL '19:00' HOUR TO MINUTE FROM DUAL UNION ALL
    SELECT 'FRI', INTERVAL '09:00' HOUR TO MINUTE, INTERVAL '18:00' HOUR TO MINUTE FROM DUAL;
    

    クエリ1

    WITH days ( id, start_date, day_start, day_end, end_date ) AS (
      SELECT ROWNUM,
             start_date,
             start_date,
             LEAST( TRUNC( start_date ) + INTERVAL '1' DAY, end_date ),
             end_date
      FROM   times
    UNION ALL
      SELECT id,
             start_date,
             day_end,
             LEAST( day_end + INTERVAL '1' DAY, end_date ),
             end_date
      FROM   days
      WHERE  day_end < end_date
    )
    SELECT start_date,
           end_date,
           SUM( shift_end - shift_start ) AS days_worked_on_shift
    FROM   (
      SELECT ID,
             start_date,
             end_date,
             GREATEST( day_start, TRUNC( day_start ) + start_time ) AS shift_start,
             LEAST( day_end, TRUNC( day_start ) + end_time ) AS shift_end
      FROM   days d
             INNER JOIN
             weekly_shifts w
             ON ( TO_CHAR( d.day_start, 'DY' ) = w.shift_day )
    )
    GROUP BY id, start_date, end_date;
    

    結果

    START_DATE          END_DATE            DAYS_WORKED_ON_SHIFT
    ------------------- ------------------- --------------------
    2017-02-21 07:52:32 2017-02-22 09:56:32 0.414259259259259259
    2017-02-21 09:52:32 2017-02-23 17:52:32 1.078148148148148148
    



    1. GroupConcatMysqlの個別の値ごとに発生数を取得する方法を改善する

    2. MySQL:varchar(255)UNIQUE列をUNIQUEテキストNOT NULLに変更する方法は?

    3. Postgresは読み取りアクセスのためにCSVファイルを開くことができません:許可が拒否されました

    4. mysqlステートメントの*アスタリスクはどういう意味ですか?