3

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

table 1:

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

name并且time是字符

table 2:

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

name并且time是字符

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

4

2 回答 2

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

于 2018-03-30T18:25:12.113 回答
1

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

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

间隔

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_DSINTERVAL字符串转换为.CHAR, VARCHAR2, NCHAR, or NVARCHAR2INTERVAL 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 hours。该EXTRACT函数用于获取所需HH:MM格式的 o/p。您可以使用该EXTRACT函数从间隔(天.小时、分钟、秒..)中检索任何组件,并修改查询以显示所需的格式。

演示

于 2018-03-31T07:47:59.277 回答