9-固定時間段內的工作時間求和
阿新 • • 發佈:2021-02-07
類似於使用打卡時間求一段時間內的工作時間之和,給出的表資料大致是這樣的。
ID:車間ID
gid:裝置id
ACTIVITY:型別 ,有兩種:in 開啟, out 關閉
時間:啟動或者關閉的時間點
現在的要求是輸入一個開始時間 和一個結束時間 求每臺裝置(同一車間的同一裝置)的在此範圍內的工作時間。 異常資料處理: 1.重複資料需要去重 2.同一臺裝置連續的in 需要取最後一個 3.連續的out需要取第一個 4.如果一個時間段的開始時間小於輸入的開始時間,則按照輸入開始時間計算 5.如果一個時間段的結束時間大於輸入的結束時間,則按照輸入結束時間計算 上面的表輸入
最終得到的結果是
資料在下方:
CREATE TABLE "SYSTEM"."AAREPORT" ( "ID" VARCHAR2(255 BYTE) ,
"ACTIVITY" VARCHAR2(255 BYTE) , "TXNTIMESTAMP" DATE ,
"GID" VARCHAR2(255 BYTE) )TABLESPACE "SYSTEM"LOGGINGNOCOMPRESSPCTFREE 10INITRANS 1STORAGE
( INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)PARALLEL 1NOCACHEDISABLE ROW MOVEMENT;
-- ------------------------------ Records of AAREPORT-- ----------------------------
INSERT INTO "SYSTEM"."AAREPORT" VALUES ( '1', 'in', TO_DATE('2020-07-15 08:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'a');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('1', 'out', TO_DATE('2020-07-16 03:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'a');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('2', 'in', TO_DATE('2020-07-15 08:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'b');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('3', 'in', TO_DATE('2020-07-15 10:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'a');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('3', 'out', TO_DATE('2020-07-16 02:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'a');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('3', 'in', TO_DATE('2020-07-16 10:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'a');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('4', 'in', TO_DATE('2020-07-16 01:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'a');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('4', 'out', TO_DATE('2020-07-16 02:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'a');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('4', 'in', TO_DATE('2020-07-16 09:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'a');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('4', 'out', TO_DATE('2020-07-17 21:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'a');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('1', 'in', TO_DATE('2020-07-15 07:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'b');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('1', 'out', TO_DATE('2020-07-16 04:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'b');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('3', 'in', TO_DATE('2020-07-18 12:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'b');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('3', 'in', TO_DATE('2020-07-17 08:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'b');
INSERT INTO "SYSTEM"."AAREPORT" VALUES ('3', 'out', TO_DATE('2020-07-17 18:00:00', 'SYYYY-MM-DD HH24:MI:SS'), 'b');
答案:
with t_x as ---使用者引數輸入
(select &輸入開始時間 as start_time ,&輸入結束時間 as end_time from dual)
,
t10 as ---用於對重複資料去重和對最後無out資料的容錯
(select distinct id,gid,activity,txntimestamp
from system.aareport union all
select distinct id,gid,'out' as activity,date'4712-12-31' as txntimestamp
from system.aareport
)
,t2 as --- 對資料進行編號
(
select id,gid,activity,txntimestamp,
row_number()over(partition by id,gid order by txntimestamp) as flag
from t10
)
-----將開始時間和結束時間寫在同一行中,並對實際時間和傳入時間進行對比選取
-----最後計算總時間的和
select t3.id,t3.gid,min(greatest(t3.txntimestamp,t5.start_time)) as start_time ,
max(least(t4.txntimestamp,t5.end_time)) as end_time ,
sum(least(t4.txntimestamp,t5.end_time)-
greatest(t3.txntimestamp,t5.start_time))*24 as sum_time
from t2 t3 , t2 t4,t_x t5
where t3.id=t4.id and t3.gid =t4.gid and
t3.flag=t4.flag-1 and t3.txntimestamp <=t5.end_time
and t4.txntimestamp >=t5.start_time
and t3.activity ='in'
and t4.activity ='out'
group by t3.id ,t3.gid