0

12:00 = 13:30 のように、開始時刻と終了時刻が何時間にもわたるさまざまな活動の記録があります。そのアクティビティの時間が 12:00 - 1 時間、13:00、00:30 として割り当てられるように、時間を時間に割り当てる必要があります。これを達成するための最良の方法は何ですか?

テーブルの作成、挿入、および期待される結果は次のとおりです。他に何か必要な場合はお知らせください。ありがとう!

CREATE TABLE Z_SCHED_ACTIVITY
(
SCHED_ACTIVITY_ID decimal(38),
STARTTIME timestamp,
ENDTIME timestamp,
ACTIVITY_ID decimal(38),
EMPLOYEE_ID decimal(38),
SHIFT_ID decimal(38)
);

インサート:

INSERT INTO Z_SCHED_ACTIVITY  VALUES (16452556,{ts '2013-04-11 01:00:00.0'},{ts '2013-04-11 02:00:00.0'},-4107,5217,252849);
INSERT INTO Z_SCHED_ACTIVITY  VALUES (16456677,{ts '2013-04-11 05:30:00.0'},{ts '2013-04-11 05:45:00.0'},-4104,1878,249440);
INSERT INTO Z_SCHED_ACTIVITY  VALUES (16457993,{ts '2013-04-11 03:52:00.0'},{ts '2013-04-11 04:07:00.0'},-4104,5217,252849);
INSERT INTO Z_SCHED_ACTIVITY  VALUES (16613742,{ts '2013-04-11 08:00:00.0'},{ts '2013-04-11 09:00:00.0'},-4107,1878,249440);
INSERT INTO Z_SCHED_ACTIVITY  VALUES (16613744,{ts '2013-04-11 10:30:00.0'},{ts '2013-04-11 10:45:00.0'},-4104,1878,249440);
INSERT INTO Z_SCHED_ACTIVITY  VALUES (16613744,{ts '2013-04-10 23:45.00.0'},{ts '2013-04-11 00:45:00.0'},-4104,1878,249440);

EXPECTED RESULT
Shift ID     EmployeeID            hour start                Sched Time          Activity
249440           1878            04/10/2013 23:00:00           15               -4104
249440           1878            04/11/2013 00:00:00           45               -4104
249440           1878            04/11/2013 05:00:00           15               -4104
249440           1878            04/11/2013 08:00:00           60               -4107
249440           1878            04/11/2013 10:00:00           15               -4104
252849           5217            04/11/2013 01:00:00           60               -4107
252849           5217            04/11/2013 03:00:00            8               -4104
252849           5217            04/11/2013 04:00:00            7               -4104
4

1 に答える 1

0

便利なトリックは、データから可能なすべての時間間隔を生成し、それを結合の一部として使用することです。次に例を示します。

select min_start + ((level - 1) / 24) as hour_start,
    min_start + (level / 24) as hour_end
from (
    select trunc(min(starttime), 'HH') as min_start,
        trunc(max(endtime), 'HH') as max_end
    from z_sched_activity
)
connect by level <= ((max_end - min_start) * 24) + 1;

HOUR_START          HOUR_END
------------------- -------------------
04/10/2013 23:00:00 04/11/2013 00:00:00
04/11/2013 00:00:00 04/11/2013 01:00:00
04/11/2013 01:00:00 04/11/2013 02:00:00
04/11/2013 02:00:00 04/11/2013 03:00:00
04/11/2013 03:00:00 04/11/2013 04:00:00
04/11/2013 04:00:00 04/11/2013 05:00:00
04/11/2013 05:00:00 04/11/2013 06:00:00
04/11/2013 06:00:00 04/11/2013 07:00:00
04/11/2013 07:00:00 04/11/2013 08:00:00
04/11/2013 08:00:00 04/11/2013 09:00:00
04/11/2013 09:00:00 04/11/2013 10:00:00
04/11/2013 10:00:00 04/11/2013 11:00:00

12 rows selected.

一致する期間でベース テーブルに結合できます。

with hours as (
    select min_start + ((level - 1) / 24) as hour_start,
        min_start + (level / 24) as hour_end
    from (
        select trunc(min(starttime), 'HH') as min_start,
            trunc(max(endtime), 'HH') as max_end
        from z_sched_activity
    )
    connect by level <= ((max_end - min_start) * 24) + 1
)
select h.hour_start, h.hour_end, zsa.sched_activity_id, zsa.starttime,
    zsa.endtime, zsa.activity_id, zsa.employee_id, zsa.shift_id
from hours h
join z_sched_activity zsa
on not (zsa.starttime >= h.hour_end or zsa.endtime < h.hour_start)
order by h.hour_start, zsa.sched_activity_id, zsa.starttime;

少し面倒なので出力は表示しませんが、ベース データstarttimeendtime.

次に、これらの各疑似レコードが一致する期間にある時間を計算できます。

with hours as (
    select min_start + ((level - 1) / 24) as hour_start,
        min_start + (level / 24) as hour_end
    from (
        select trunc(min(starttime), 'HH') as min_start,
            trunc(max(endtime), 'HH') as max_end
        from z_sched_activity
    )
    connect by level <= ((max_end - min_start) * 24) + 1
)
select zsa.shift_id, zsa.employee_id, h.hour_start,
    (60*24) * (least(h.hour_end, zsa.endtime)
        - greatest(h.hour_start, zsa.starttime)) as sched_time,
    zsa.activity_id
from hours h
join z_sched_activity zsa
on not (zsa.starttime >= h.hour_end or zsa.endtime < h.hour_start)
order by zsa.shift_id, zsa.employee_id, h.hour_start, zsa.sched_activity_id;

  SHIFT_ID EMPLOYEE_ID HOUR_START          SCHED_TIME ACTIVITY_ID
---------- ----------- ------------------- ---------- -----------
    249440        1878 04/10/2013 23:00:00         15       -4104
    249440        1878 04/11/2013 00:00:00         45       -4104
    249440        1878 04/11/2013 05:00:00         15       -4104
    249440        1878 04/11/2013 08:00:00         60       -4107
    249440        1878 04/11/2013 09:00:00          0       -4107
    249440        1878 04/11/2013 10:00:00         15       -4104
    252849        5217 04/11/2013 01:00:00         60       -4107
    252849        5217 04/11/2013 02:00:00          0       -4107
    252849        5217 04/11/2013 03:00:00          8       -4104
    252849        5217 04/11/2013 04:00:00          7       -4104

10 rows selected.

ここで少し奇妙なのは、 of を持つレコードendtime2013-04-11 02:00:00.0場合、その endtime は間違いなく次の時間の開始時であり、 of を持つレコードsched_timeがゼロになることです。where計算を繰り返して句でそれらを除外するか、これを外側selectでラップしてそれらを削除するか、別の結合条件を追加してまったく考慮されないようにすることができます。

...
from hours h
join z_sched_activity zsa
on not (zsa.starttime >= h.hour_end or zsa.endtime < h.hour_start)
and zsa.endtime != h.hour_start
...

  SHIFT_ID EMPLOYEE_ID HOUR_START          SCHED_TIME ACTIVITY_ID
---------- ----------- ------------------- ---------- -----------
    249440        1878 04/10/2013 23:00:00         15       -4104
    249440        1878 04/11/2013 00:00:00         45       -4104
    249440        1878 04/11/2013 05:00:00         15       -4104
    249440        1878 04/11/2013 08:00:00         60       -4107
    249440        1878 04/11/2013 10:00:00         15       -4104
    252849        5217 04/11/2013 01:00:00         60       -4107
    252849        5217 04/11/2013 03:00:00          8       -4104
    252849        5217 04/11/2013 04:00:00          7       -4104

8 rows selected.
于 2013-04-15T11:13:08.733 に答える