如何在hh24中汇总存储时间的列:mi:ss在Oracle Sql中?

时间:2018-05-29 11:43:03

标签: sql oracle sum to-date

我有一个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实现这一目标吗?

2 个答案:

答案 0 :(得分:2)

您可以将时间间隔计算为小数天数并总结:

SQL Fiddle

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');