[英]Oracle SQL To_Char(interval) is not using my format string?
在 SQL 的以下位中,我想以 HH:MM:SS 格式打印一个间隔(实际上是几秒)。 我将秒数转换为间隔,然后尝试使用 TO_CHAR 日期格式。 Oracle 服务器忽略我的模式并打印一个完整的时间戳,日期和微秒中的字符为零。 我究竟做错了什么?
CASE WHEN (TR.RUN_LENGTH > 0) THEN TO_CHAR(NUMTODSINTERVAL(TR.RUN_LENGTH,'second'), 'HH24:MI:SS')
ELSE '0' END AS RUN_LENGTH,
我得到:+000000000 00:03:22.000000000
正如您所观察到的, to_char()
不适用于间隔。 所以,不要考虑间隔。 相反,您有几秒钟的时间,并且想要转换为 HH:MM:SS 格式的字符串。
使用算术和字符串运算:
select lpad(floor(tr.run_length / 3600), 2, '0') || ':' || lpad(mod(floor(tr.run_length / 60), 60), 2, '0') || ':' || lpad(mod(tr.run_length, 60), 2, '0') as hhmmss
from (select 1 as run_length from dual union all
select 10 as run_length from dual union all
select 100 as run_length from dual union all
select 1000 as run_length from dual union all
select 10000 as run_length from dual union all
select 100000 as run_length from dual
) tr;
这是一个 db<>fiddle。
我搜索了其他相关回复; 很明显,Oracle 实际上并没有为 TO_CHAR(DSINTERVAL) 实现用户指定的格式。 正如一些人所建议的,您可以添加一个日期,然后使用日期格式。 但如果间隔超过 24 小时,则会失败。
我最终使用了 REGEXP_SUBSTRING() 但后来遇到了 Oracle 显然不支持非捕获组的问题。 我能够拼凑出这个:
REGEXP_SUBSTR(TO_CHAR(NUMTODSINTERVAL(TR.RUN_LENGTH,'second')), '^([\+0:\ ]*)(.*)(\.)',1,1,NULL,2 )
这似乎工作得很好。 它抑制任何前导零和小数秒。
如果您的时间间隔始终少于 24 小时,那么您可以使用以下方法之一:
TO_CHAR(TRUNC(SYSDATE) + NUMTODSINTERVAL(TR.RUN_LENGTH, 'second'), 'hh24:mi:ss')
REGEXP_SUBSTR(NUMTODSINTERVAL(TR.RUN_LENGTH,'second'), '\d{2}:\d{2}:\d{2}')
否则,您需要使用EXTRACT function:
SELECT
TO_CHAR(
EXTRACT(DAY FROM NUMTODSINTERVAL(TR.RUN_LENGTH,'second')) * 24
+ EXTRACT(HOUR FROM NUMTODSINTERVAL(TR.RUN_LENGTH,'second')) )
|| ':' EXTRACT(MINUTE FROM NUMTODSINTERVAL(TR.RUN_LENGTH,'second')
|| ':' TRUNC(EXTRACT(SECOND FROM NUMTODSINTERVAL(TR.RUN_LENGTH,'second'))
如果 output 需要,您可以选择在零件周围添加LPAD(..., 2, '0')
。
更少的代码:
to_number(
substr(to_char((LATER_timestamp - EARLIER_timestamp),'HH24:MI:SS'), 1,10) /* this is the DAY string */
) || 'd ' ||
substr(to_char((LATER_timestamp - EARLIER_timestamp),'HH24:MI:SS'),12,11) /* this is the TIME string. Milliseconds are "FLOORED". */
示例 output 是:“2d 02:59:57.31”。
尝试这个:
TO_CHAR (TRUNC (SYSDATE) + NUMTODSINTERVAL ((TR.RUN_LENGTH, 'second'),
'hh24:mi:ss' )
NUMTODSINTERVAL 的文档说它返回一个字符串文字,所以 to_char 没有效果。 上面的这个 hack 只取当前日期/时间(sysdate),截断 HH:mm:ss 组件,然后加回您指定的#seconds,然后将其格式化为仅显示 HH:MM:SS 值
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.