这是一个表,其中包含一个任务的员工工作时间,该任务可能在两天(或更长时间)之间跨越,也可能不跨越。
需要帮助以按小时,分钟和秒的时间单独汇总每个员工和任务ID的日期。
表示例:
Emp_ID | Task_ID | Task_start_date_time | Task_stop_date_time
A1 | 123 | 01/13/2016 11:30:30 PM | 01/14/2016 12:30:30 AM
B1 | 124 | 01/16/2016 10:30:35 PM | 01/18/2016 2:30:35 AM
C1 | 125 | 01/19/2016 9:30:20 AM | 01/19/2016 2:30:20 PM
D1 | 126 | 01/20/2016 3:15:25 AM | 01/21/2016 2:25:25 PM
所需的SQL结果集:
A1 | 123 | 01/13/2016 | 00:29:30
A1 | 123 | 01/14/2016 | 04:30:30
B1 | 124 | 01/16/2016 | 01:29:25
B1 | 124 | 01/17/2016 | 24:00:00
B1 | 124 | 01/18/2016 | 02:30:35
C1 | 125 | 01/19/2016 | 05:00:00
D1 | 126 | 01/20/2016 | 20:44:35
D1 | 126 | 01/20/2016 | 14:25:25
提前致谢。
另外一个:eid和tid有多行?并且需要以相同的方式聚合。
表示例:
Emp_ID | Task_ID | Task_start_date_time | Task_stop_date_time
A1 | 123 | 01/13/2016 11:30:30 PM | 01/14/2016 12:30:30 AM
A1 | 123 | 01/14/2016 10:30:35 AM | 01/14/2016 2:30:35 PM
B1 | 124 | 01/16/2016 10:30:35 PM | 01/18/2016 2:30:35 AM
C1 | 125 | 01/19/2016 9:30:20 AM | 01/19/2016 2:30:20 PM
D1 | 126 | 01/20/2016 3:15:25 AM | 01/21/2016 2:25:25 PM
所需的SQL结果集:
A1 | 123 | 01/13/2016 | 00:29:30
A1 | 123 | 01/14/2016 | 08:30:30
B1 | 124 | 01/16/2016 | 01:29:25
B1 | 124 | 01/17/2016 | 24:00:00
B1 | 124 | 01/18/2016 | 02:30:35
C1 | 125 | 01/19/2016 | 05:00:00
D1 | 126 | 01/20/2016 | 20:44:35
答案 0 :(得分:0)
其中一种可能性:
with data as (
select emp_id eid, task_id tid, task_start_date_time d1, task_stop_date_time d2,
trunc(task_stop_date_time)-trunc(task_start_date_time)+1 cnt from tasks),
rec(eid, tid, d1, d2, cnt, rn) as (
select eid, tid, d1, d2, cnt, 1 from data
union all
select eid, tid, d1, d2, cnt, rn+1 from rec where rn+1<=cnt),
res as (
select eid, tid, rn, trunc(d1)+rn-1 dt,
least(d2, trunc(d1)+rn) - greatest(d1, trunc(d1)+rn-1) diff
from rec)
select eid, tid, dt,
to_char(trunc(diff*24), 'fm00')||':'||
to_char(trunc(mod(diff*24*60, 60)), 'fm00')||':'||
to_char(trunc(mod(diff*24*60*60, 60 )), 'fm00') diff
from res order by eid, rn
步骤:
data
- 此处我根据start_date和end_date之间的差异添加了包含天数的列cnt
,rec
- 这会为输入数据中的每一行生成所需的行数,res
- 添加了适当值的差异,这个差异以天为单位,diff
从天数转换为hh:mm:ss
格式。运行此查询需要Oracle 11g。我将表命名为tasks
,下面是示例数据和输出。
create table tasks (Emp_ID varchar2(2), Task_ID number(6), Task_start_date_time date, Task_stop_date_time date);
insert into tasks values ('A1', 123, timestamp '2016-01-13 23:30:30', timestamp '2016-01-14 00:30:30');
insert into tasks values ('B1', 124, timestamp '2016-01-16 22:30:35', timestamp '2016-01-18 02:30:35');
insert into tasks values ('C1', 125, timestamp '2016-01-19 09:30:20', timestamp '2016-01-19 14:30:20');
insert into tasks values ('D1', 126, timestamp '2016-01-20 03:15:25', timestamp '2016-01-21 14:25:25');
输出:
EID TID DT DIFF
--- ---------- -------- -----------
A1 123 16/01/13 00:29:29
A1 123 16/01/14 00:30:30
B1 124 16/01/16 01:29:25
B1 124 16/01/17 24:00:00
B1 124 16/01/18 02:30:34
C1 125 16/01/19 05:00:00
D1 126 16/01/20 20:44:35
D1 126 16/01/21 14:25:25
更新:如果您要对值进行分组,就像在评论中提到的那样,您需要为每一天添加group by子句 - 请参阅子查询res
和最终选择中的更改。< / p>
insert into tasks values ('A1', 123,
timestamp '2016-01-14 10:30:35',
timestamp '2016-01-14 14:30:35');
with data as (
select emp_id eid, task_id tid, task_start_date_time d1, task_stop_date_time d2,
trunc(task_stop_date_time)-trunc(task_start_date_time)+1 cnt from tasks),
rec(eid, tid, d1, d2, cnt, rn) as (
select eid, tid, d1, d2, cnt, 1 from data
union all
select eid, tid, d1, d2, cnt, rn+1 from rec where rn+1<=cnt),
res as (
select eid, tid, trunc(d1)+rn-1 dt,
sum(least(d2, trunc(d1)+rn) - greatest(d1, trunc(d1)+rn-1)) diff
from rec group by eid, tid, trunc(d1)+rn-1)
select eid, tid, dt,
to_char(trunc(diff*24), 'fm00')||':'||
to_char(trunc(mod(diff*24*60, 60)), 'fm00')||':'||
to_char(trunc(mod(diff*24*60*60, 60 )), 'fm00') diff
from res order by eid, tid, dt
输出(更改在第2行:数据第一行30分30秒,第二行4小时):
EID TID DT DIFF
--- ---------- ----------- -----------
A1 123 2016-01-13 00:29:29
A1 123 2016-01-14 04:30:30
B1 124 2016-01-16 01:29:25
B1 124 2016-01-17 24:00:00
B1 124 2016-01-18 02:30:34
C1 125 2016-01-19 05:00:00
D1 126 2016-01-20 20:44:35
D1 126 2016-01-21 14:25:25