将格式为35:23:12的VARCHAR转换为我可以求和的数据类型

时间:2019-04-03 13:28:14

标签: sql oracle

我有以下格式的varchar数据:

示例1-00:00:06

示例1-372:25:27

它表示小时:分钟:秒

我需要能够将其转换为数据类型,我可以对其求和,我只希望小时和分钟。 反正有转换此数据,以便我可以与查询求和吗?

NB,我无法更改在其他人的数据库上做一些工作的表。

2 个答案:

答案 0 :(得分:1)

使用正则表达式将拆分您的字符串,以便您可以使用它们

i: &{{6 2019-04-03 15:11:37.822100431 +0200 CEST m=+0.001291882} 7} *main.A
2019/04/03 15:11:37 Insert i no table found for type: 
exit status 1

答案 1 :(得分:0)

如@Walucas所示,您可以使用正则表达式提取字符串值的小时,分​​钟和秒部分(假设它们的格式均相同):

select statustracking,
  regexp_substr(statustracking ,'(.*?)(:|$)', 1, 1, null, 1) as h,
  regexp_substr(statustracking ,'(.*?)(:|$)', 1, 2, null, 1) as m,
  regexp_substr(statustracking ,'(.*?)(:|$)', 1, 3, null, 1) as s
from your_table;

STATUSTRACKING H         M         S        
-------------- --------- --------- ---------
00:00:06       00        00        06       
372:25:27      372       25        27       

然后将它们转换为数字并乘以多个元素,使其全部代表秒数(例如),然后将它们加在一起得到字符串表示的秒总数:

select statustracking,
  3600 * to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 1, null, 1)) as h,
  60 * to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 2, null, 1)) as m,
  to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 3, null, 1)) as s,
  3600 * to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 1, null, 1))
    + 60 * to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 2, null, 1))
    + to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 3, null, 1)) as total_s
from your_table;

STATUSTRACKING          H          M          S    TOTAL_S
-------------- ---------- ---------- ---------- ----------
00:00:06                0          0          6          6
372:25:27         1339200       1500         27    1340727

然后将这些总数相加:

select sum(
    3600 * to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 1, null, 1))
      + 60 * to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 2, null, 1))
      + to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 3, null, 1))
  ) as total_s
from your_table;

   TOTAL_S
----------
   1340733

然后反转转换过程,将总秒数分解为小时,分钟和-如果需要,将秒数:

select floor(total_s / 3600) as h,
       floor(mod(total_s, 3600) / 60) as m,
       mod(total_s, 60) as s
from (
  select sum(
      3600 * to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 1, null, 1))
        + 60 * to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 2, null, 1))
        + to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 3, null, 1))
    ) as total_s
  from your_table
);

         H          M          S
---------- ---------- ----------
       372         25         33

如果您想返回字符串格式,则可以将它们与冒号连接在一起,并用lpad()to_char()用零左填充:

select to_char(total_s / 3600, 'FM9999900')
       ||':'|| to_char(mod(total_s, 3600) / 60, 'FM00')
       ||':'|| to_char(mod(total_s, 60), 'FM00')
       as total_time
from (
  select sum(
      3600 * to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 1, null, 1))
        + 60 * to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 2, null, 1))
        + to_number(regexp_substr(statustracking ,'(.*?)(:|$)', 1, 3, null, 1))
    ) as total_s
  from your_table
);

TOTAL_TIME      
----------------
372:26:33

db<>fiddle