使用 to_char 格式化间隔

发布于 2024-07-23 07:25:39 字数 226 浏览 13 评论 0原文

以下 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?

Following SQL command

select TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00'))) from table1

produces a result of the format: +000000000 00:03:01.954000.

Is it possible to enter a special format in the to_char function in order to get
a result of format: +00 00:00:00.000?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

雪化雨蝶 2024-07-30 07:25:39

如果您想要降低精度,您可以转换结果:

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

这不是很优雅,但似乎这是处理微秒精度的唯一方法。

you could cast the result if you want less precision:

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

Edit following OP comment:


From The Oracle Documentation (11gr1):

Interval datatypes do not have format models. Therefore, to adjust their presentation, you must combine character functions such as EXTRACT and concatenate the components.

It seems you will have to manually use EXTRACT to achieve the desired output:

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


This is not very elegant but it seems it is the only way to deal with microseconds precision.

眼睛会笑 2024-07-30 07:25:39

to_char() 似乎有固定格式:( 所以 regexp_substr 可能是一个选项,例如:

SELECT regexp_substr (TO_DSINTERVAL ('10 10:00:00'), '\d{2} \d{2}:\d{2}:\d{2}\.\d{3}') t_interval FROM dual

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
当梦初醒 2024-07-30 07:25:39

我意识到这根本不聪明,也不是您正在寻找的特殊格式字符串,但这个答案确实有效,因为输出是固定长度的:

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;

它也只是截断秒的小数部分而不是四舍五入,但我假设从你的例子无论如何它们都只是零。

这是更大的尴尬,但我无法抗拒:

SELECT SUBSTR(REPLACE(TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00')))
                     , '0000000', '')
             , 1, 16)
  FROM table1;

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;
丢了幸福的猪 2024-07-30 07:25:39

线程死灵的轻微情况,但是我在搜索如何格式化间隔时遇到了这个问题,所以我认为值得添加此评论。

Oracle 文档,添加时间戳间隔会产生时间戳,因此通过添加具有零时间元素的常量时间戳,您可以使用标准 to_char 日期时间的格式元素 ...

SELECT TO_CHAR( TIMESTAMP'1969-12-31 00:00:00' + TO_DSINTERVAL('0 00:03:01.954321'),
  'HH24:MI:SS.FF3' ) FROM dual;

但是,如果您的间隔可能大于一天,则会出现问题。 没有会产生 0 的日期的格式元素。“DDD”是一年中的某一天,因此在上面的示例中将为 365,如果间隔大于一天,则为 1 或更多。 不过只要您的间隔时间少于 24 小时就可以。

应该补充一下这是在 11g 上,所以很可能不适用于 OP。

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.

纸伞微斜 2024-07-30 07:25:39
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

只需添加日期并使用 to_char ('HH24:MI') !

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') !

混浊又暗下来 2024-07-30 07:25:39

您可以使用正则表达式删除最后一部分(或任何部分)
Oracle REGEXP_REPLACE 就是这样做的。

从 table1 中选择 REGEXP_REPLACE( TO_CHAR(NVL(arg1 - arg2, TO_DSINTERVAL('0 00:00:00'))), '..*')

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

此岸叶落 2024-07-30 07:25:39
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.
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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文