在INTERVAL Oracle中插入子查询

时间:2016-06-24 08:24:55

标签: sql oracle subquery intervals

这项工作很好:

SELECT INTERVAL '1:0:0' HOUR TO SECOND FROM   dual;

我试图从表中选择一些值并将其用作INTERVAL。如何使用子查询而不是' 1:0:0'?

SELECT INTERVAL (SELECT some_varchar_value from some_table) HOUR TO SECOND FROM DUAL;

但INTERVAL期望在单引号内表达' '

1 个答案:

答案 0 :(得分:1)

您可以使用the TO_DSINTERVAL() function

SELECT TO_DSINTERVAL(some_varchar_value)
FROM some_table;

但您的字符串值必须采用正确的格式。如果如图所示,只需几小时,几分钟和几秒钟,您需要在天数之前添加一个虚拟零:

with some_table(some_varchar_value) as (
  select '1:0:0' from dual
)
SELECT TO_DSINTERVAL('0 ' || some_varchar_value)
FROM some_table;

TO_DSINTERV
-----------
0 1:0:0.0  

如果您的小时值大于24,那么您需要将其分为整天和剩余小时数:

with some_table(some_varchar_value) as (
  select '1:2:3' from dual
  union all select '99:45:15' from dual
)
SELECT TO_DSINTERVAL(
    floor(to_number(regexp_substr(some_varchar_value, '[^:]+', 1, 1)) / 24)
    || ' ' || mod(to_number(regexp_substr(some_varchar_value, '[^:]+', 1, 1)), 24)
    || ':' || regexp_substr(some_varchar_value, '[^:]+', 1, 2)
    || ':' || regexp_substr(some_varchar_value, '[^:]+', 1, 3)
  )
FROM some_table;

TO_DSINTERV
-----------
0 1:2:3.0  
4 3:45:15.0

其内部将原始字符串拆分为单独的小时,分​​钟和秒组件;然后将小时分为floor(hours / 24)天和剩余小时mod(hours, 24)。您可以更清楚地看到:

with some_table(some_varchar_value) as (
  select '99:59:30' from dual
)
SELECT regexp_substr(some_varchar_value, '[^:]+', 1, 1), regexp_substr(some_varchar_value, '[^:]+', 1, 2), regexp_substr(some_varchar_value, '[^:]+', 1, 3)
FROM some_table;

with some_table(some_varchar_value) as (
  select '1:2:3' from dual
  union all select '99:45:15' from dual
)
SELECT regexp_substr(some_varchar_value, '[^:]+', 1, 1) as raw_hh,
  regexp_substr(some_varchar_value, '[^:]+', 1, 2) as raw_mi,
  regexp_substr(some_varchar_value, '[^:]+', 1, 3) as raw_ss,
  floor(to_number(regexp_substr(some_varchar_value, '[^:]+', 1, 1)) / 24) as new_dd,
  mod(to_number(regexp_substr(some_varchar_value, '[^:]+', 1, 1)), 24) as new_hh
FROM some_table;

RAW_HH   RAW_MI   RAW_SS       NEW_DD     NEW_HH
-------- -------- -------- ---------- ----------
1        2        3                 0          1
99       45       15                4          3