我有一个PROCESS_TIME,数据类型为VARCHAR2(32), 我将时间存储为 hh24:mi:ss , 我打算在某些分组逻辑上添加这些时间。
表格的缩小版本
CREATE TABLE "SCHEMA"."MY_TABLE"
( "MY_TABLE_ID" VARCHAR2(32 BYTE) NOT NULL ENABLE,
"START_TIME" DATE NOT NULL ENABLE,
"END_TIME" DATE NOT NULL ENABLE,
"LOAD_PROCESS_TIME" VARCHAR2(32 BYTE) DEFAULT '00:00:00',
)
和插入
的缩小版本Insert into MY_TABLE (MY_TABLE_ID,START_TIME,END_TIME,LOAD_PROCESS_TIME)
values ('8880508C9AC4441DB8E16E023F206C2F',to_date('05/11/2018 07:22','MM/DD/YYYY HH:MI'),to_date('05/11/2018 08:22','MM/DD/YYYY HH:MI'),'01:00:14');
Insert into MY_TABLE (MY_TABLE_ID,START_TIME,END_TIME,LOAD_PROCESS_TIME) values ('C858EB646A794D04B5C77779C50EBFCF',
to_date('05/12/2018 10:20','MM/DD/YYYY HH:MI'),
to_date('05/12/2018 11:20','MM/DD/YYYY HH:MI'),
'02:30:10');
预期查询
SELECT TO_CHAR(TRUNC(END_TIME, 'DD'), 'DD-MON-YY'),
sum(LOAD_PROCESS_TIME)
FROM MY_TABLE
WHERE END_TIME > SYSDATE -14
GROUP BY TRUNC(END_TIME,'DD')
ORDER BY TRUNC(END_TIME,'DD');
您能帮助我使用Oracle SQL实现这一目标吗?
答案 0 :(得分:2)
您可以将时间间隔计算为小数天数并总结:
Oracle 11g R2架构设置:
CREATE TABLE table_name ( PROCESS_TIME ) AS
SELECT '01:23:04' FROM DUAL UNION ALL
SELECT '23:00:00' FROM DUAL UNION ALL
SELECT '11:36:56' FROM DUAL;
查询1 :
SELECT SUM(
TO_DATE( PROCESS_TIME, 'HH24:MI:SS' )
- TO_DATE( '00:00:00', 'HH24:MI:SS' )
) AS num_days
FROM table_name
<强> Results 强>:
| NUM_DAYS |
|----------|
| 1.5 |
您还可以创建自定义对象来聚合INTERVAL DAY TO SECOND
数据类型:
CREATE TYPE IntervalSumType AS OBJECT(
total INTERVAL DAY(9) TO SECOND(9),
STATIC FUNCTION ODCIAggregateInitialize(
ctx IN OUT IntervalSumType
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateIterate(
self IN OUT IntervalSumType,
value IN INTERVAL DAY TO SECOND
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateTerminate(
self IN OUT IntervalSumType,
returnValue OUT INTERVAL DAY TO SECOND,
flags IN NUMBER
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateMerge(
self IN OUT IntervalSumType,
ctx IN OUT IntervalSumType
) RETURN NUMBER
);
/
CREATE OR REPLACE TYPE BODY IntervalSumType
IS
STATIC FUNCTION ODCIAggregateInitialize(
ctx IN OUT IntervalSumType
) RETURN NUMBER
IS
BEGIN
ctx := IntervalSumType( INTERVAL '0' DAY );
RETURN ODCIConst.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateIterate(
self IN OUT IntervalSumType,
value IN INTERVAL DAY TO SECOND
) RETURN NUMBER
IS
BEGIN
IF value IS NOT NULL THEN
self.total := self.total + value;
END IF;
RETURN ODCIConst.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateTerminate(
self IN OUT IntervalSumType,
returnValue OUT INTERVAL DAY TO SECOND,
flags IN NUMBER
) RETURN NUMBER
IS
BEGIN
returnValue := self.total;
RETURN ODCIConst.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateMerge(
self IN OUT IntervalSumType,
ctx IN OUT IntervalSumType
) RETURN NUMBER
IS
BEGIN
self.total := self.total + ctx.total;
RETURN ODCIConst.SUCCESS;
END;
END;
/
然后是自定义聚合函数:
CREATE FUNCTION SUM_INTERVALS( value INTERVAL DAY TO SECOND )
RETURN INTERVAL DAY TO SECOND
PARALLEL_ENABLE AGGREGATE USING IntervalSumType;
/
查询2 :
SELECT SUM_INTERVALS( TO_DSINTERVAL( '+0 '||PROCESS_TIME ) )
AS total_difference
FROM table_name
<强> Results 强>:
| TOTAL_DIFFERENCE |
|------------------|
| 1 12:0:0.0 |
更新 - 查询3 :
SELECT TO_CHAR( num_days * 24, 'FM99990' )
|| ':' || TO_CHAR( MOD( num_days * 24*60, 60 ), 'FM00' )
|| ':' || TO_CHAR( MOD( num_days * 24*60*60, 60 ), 'FM00' )
AS total_time
FROM (
SELECT SUM(
TO_DATE( PROCESS_TIME, 'HH24:MI:SS' )
- TO_DATE( '00:00:00', 'HH24:MI:SS' )
) AS num_days
FROM table_name
)
<强> Results 强>:
| TOTAL_TIME |
|------------|
| 36:00:00 |
答案 1 :(得分:0)
<强> ------------------------------答案------------- --------------------------- 强>
作为讨论的完成,有效的查询是
SELECT TO_CHAR(TRUNC(END_TIME, 'DD'), 'DD-MON-YY'),
to_char(sum(TO_DATE(LOAD_PROCESS_TIME,'HH24:MI:SS')- TO_DATE( '00:00:00', 'HH24:MI:SS' ))*24,'FM00')
|| ':'|| TO_CHAR(MOD(sum(TO_DATE(LOAD_PROCESS_TIME,'HH24:MI:SS')- TO_DATE( '00:00:00', 'HH24:MI:SS' ))*24*60,60),'FM00')
||':'|| TO_CHAR(MOD(sum(TO_DATE(LOAD_PROCESS_TIME,'HH24:MI:SS')- TO_DATE( '00:00:00', 'HH24:MI:SS' ))*24*60*60,60),'FM00')
as Days
FROM MY_TABLE
WHERE END_TIME > SYSDATE -30
GROUP BY TRUNC(END_TIME,'DD')
ORDER BY TRUNC(END_TIME,'DD');