如何用oracle中的数据类型char计算总和时间

时间:2018-03-30 17:59:37

标签: sql oracle oracle18c

我正在尝试使用2个表中的oracle中的数据类型char来创建一个查询来对记录进行求和。我有这样的表:

table 1:

name             time_rent
---------------- -----------
james            07:30

nametime是char

table 2:

name             time_expired
---------------- -----------
james            18:30

nametime是char

如何使用sum显示记录获取总时间(持续时间),是否可能?我使用Oracle Database 18c企业版在Oracle Live SQL中对其进行编码和测试。

2 个答案:

答案 0 :(得分:1)

WITH x AS (
  SELECT t1.time_rent AS t1,
         t2.time_rent AS t2,
         ((SUBSTR(t1.time_rent,1,2) * 3600) + (SUBSTR(t1.time_rent,4,2) * 60)
         + (SUBSTR(t2.time_rent,1,2) * 3600) + (SUBSTR(t2.time_rent,4,2) * 60)) AS t 
   FROM table1 t1 
   INNER JOIN Table2 t2 
   ON t1.name=t2.name
  ),
y AS(
   SELECT t1,
          t2,
          numtodsinterval(t,'second') AS t
          FROM x
)
SELECT T1,
       T2,
       (EXTRACT(day FROM t) * 24 + EXTRACT(hour FROM t) ||':' || 
       EXTRACT(minute FROM t) ||':' || EXTRACT(second FROM t)) AS duration 
       FROM y

<强>输出

T1      T2      DURATION
07:30   18:30   26:0:0

现场演示

  

http://sqlfiddle.com/#!4/aaa519/12

答案 1 :(得分:1)

向您提出的重要建议:请勿将时间间隔存储为字符串(CHAR/ VARCHAR2)。它使编写查询时对它们的操作更难实现,并且对大型数据集执行效率低下。

Oracle为您提供了两种数据类型,精确地用于数据库中您希望存储的间隔记录。

INTERVAL

INTERVAL YEAR [(year_precision)] TO MONTH - 以年和月为单位存储一段时间

INTERVAL DAY [(day_precision)] TO SECOND [(fractional_seconds)] - 存储一段时间     天,小时,分钟和秒

第二种类型对于将所需值存储为INTERVAL .. HOUR to MINUTE非常有用。

例如: - INTERVAL '07:30' HOUR TO MINUTE

因此,求和操作本来就是time_rent + time_expired,这可能使操作更容易。现在,由于您已将它们存储为字符,因此Oracle确实提供了救援功能:

TO_DSINTERVAL - TO_DSINTERVALCHAR, VARCHAR2, NCHAR, or NVARCHAR2数据类型的字符串转换为INTERVAL DAY TO SECOND

因此,将DAY组件和秒组件(零)附加到时间列将有助于将它们转换为INTERVAL类型:TO_DSINTERVAL('000 '|| time_rent|| ':00')

因此,您的最终查询看起来就像。

WITH t
     AS (SELECT t1.name,
                  TO_DSINTERVAL('000 '||    time_rent|| ':00')
                + TO_DSINTERVAL('000 '|| time_expired|| ':00') AS intv
         FROM   table1 t1
                join table2 t2
                        ON t1.name = t2.name)
SELECT name,
       EXTRACT(day FROM intv) * 24 + EXTRACT(hour FROM intv) --hours
       || ':'
       || EXTRACT(minute FROM intv) as duration  -- minutes
FROM   t;  

由于添加操作使总持续时间超过24小时(26),因此默认情况下该间隔将被视为1 day 2 hoursEXTRACT函数用于获取所需HH:MM格式的o / p。您可以使用EXTRACT函数从间隔(day.hour,minute,second ..)中检索任何组件,并修改查询以所需格式显示。

Demo