这项工作很好:
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期望在单引号内表达' '
答案 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