遵循 SQL 命令
select TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00'))) from table1
产生以下格式的结果:+000000000 00:03:01.954000。
是否可以在 to_char 函数中输入特殊格式以获得格式结果:+00 00:00:00.000?
如果你想要更低的精度,你可以转换结果:
SQL> SELECT TO_DSINTERVAL('10 10:00:00') t_interval FROM dual;
T_INTERVAL
-----------------------------------------------------------
+000000010 10:00:00.000000000
SQL> SELECT CAST(TO_DSINTERVAL('10 10:00:00')
2 AS INTERVAL DAY(2) TO SECOND(3)) t_interval
3 FROM dual;
T_INTERVAL
-----------------------------------------------------------
+10 10:00:00.000
编辑以下 OP 评论:
来自Oracle 文档 (11gr1):
区间数据类型没有格式模型。因此,要调整它们的呈现方式,就必须结合EXTRACT等字符函数,并串联组件。
看来您将不得不手动使用 EXTRACT 来实现所需的输出:
SQL> SELECT to_char(extract(DAY FROM t_interval), 'fmS99999') || ' ' ||
2 to_char(extract(HOUR FROM t_interval), 'fm00') || ':' ||
3 to_char(extract(MINUTE FROM t_interval), 'fm00') || ':' ||
4 to_char(extract(SECOND FROM t_interval), 'fm00.000')
5 FROM (SELECT TO_DSINTERVAL('10 01:02:55.895') t_interval FROM dual)
6 ;
TO_CHAR(EXTRACT(DAYFROMT_INTER
------------------------------
+10 01:02:55.895
这不是很优雅,但它似乎是处理微秒精度的唯一方法。
to_char() seems to have fixed format :( so regexp_substr may be an option, e.g.:
SELECT regexp_substr (TO_DSINTERVAL ('10 10:00:00'), '\d{2} \d{2}:\d{2}:\d{2}\.\d{3}') t_interval FROM dual
I realize it's not clever at all, nor is it the special format string you're looking for, but this answer does work, given that the output is fixed length:
SELECT SUBSTR(TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00'))), 1, 1)
|| SUBSTR(TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00'))), 9, 2)
|| ' '
|| SUBSTR(TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00'))), 12, 12)
FROM table1;
It also just truncs the fractional seconds instead of rounding, but I assume from your example they're all just zeros anyway.
This is an even greater embarrassment, but I couldn't resist:
SELECT SUBSTR(REPLACE(TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00')))
, '0000000', '')
, 1, 16)
FROM table1;
Slight case of thread necromancy, however I came across this question while searching for how to format an interval, so I thought it was worth adding this comment.
From the Oracle documentation, adding a timestamp to an interval results in a timestamp, so by adding a constant timestamp with zero time elements you can then use the standard to_char format elements for datetime ...
SELECT TO_CHAR( TIMESTAMP'1969-12-31 00:00:00' + TO_DSINTERVAL('0 00:03:01.954321'),
'HH24:MI:SS.FF3' ) FROM dual;
However, there is an issue if you intervals could be greater than a day. There is no format element for days that will yield 0. "DDD" is day of the year, so would be 365 in the example above, or 1 or more if the interval was greater then a day. This is fine as long as your intervals are less than 24 hours though.
Should add this is on 11g so may well not have be applicable to the OP.
SELECT W.SHIFT_NUMB || ' c: ' ||
TO_CHAR(TO_DATE('01.01.2012', 'dd.mm.yyyy') + W.TIMEFROM, 'HH24:MI') ||
' по: ' ||
TO_CHAR(TO_DATE('01.01.2012', 'dd.mm.yyyy') + W.TIMETO, 'HH24:MI'),
w.ID
FROM AC_WORK_SHIFT W
WHERE W.CLIENT_ID = GC
Just add date and use to_char ('HH24:MI') !
You can strip out the last part (or any part) with regular expression Oracle REGEXP_REPLACE does just that.
select REGEXP_REPLACE( TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00'))), '..*') from table1
SQL> SELECT
2 TO_CHAR(TIMESTAMP '1969-12-31 00:00:00' + to_dsinterval('0 00:03:01.954321'),
3 '"T minus" HH24 "hours" MI "minutes" SS.FF3 "seconds."'
4 ) AS elapsed_time
5 FROM
6 dual;
ELAPSED_TIME
-------------------------------------------
T minus 00 hours 03 minutes 01.954 seconds.