【问题标题】:how to calculate sum time with data type char in oracle如何在oracle中使用数据类型char计算总和时间
【发布时间】:2018-03-30 17:59:36
【问题描述】:

我正在尝试创建一个查询来汇总来自 2 个不同表的 oracle 中数据类型 char 的记录。我有这样的表:

table 1:

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

nametime 是字符

table 2:

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

nametime 是字符

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

【问题讨论】:

  • 总是同一天吗?
  • 请添加一些有用的测试数据并显示您的查询结果

标签: sql oracle oracle18c


【解决方案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

【讨论】:

    【解决方案2】:

    给您的重要建议:请不要将时间间隔存储为字符串 (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 函数从时间间隔(天.小时、分钟、秒...)中检索任何组件并修改查询以显示所需的格式。

    Demo

    【讨论】:

    • 感谢您的建议,我真的很感激 :) 我会从您的建议中学到更多。
    • @ignito 。不客气。只是另一条建议。另一个(接受的)答案使用了太多不必要的构造(可能是从其他地方复制的!),这对您的要求不是必需的。因此,如果您清楚地了解它们,请使用它..
    猜你喜欢
    • 1970-01-01
    • 2017-07-23
    • 2022-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-19
    • 2020-10-17
    • 1970-01-01
    相关资源
    最近更新 更多