我想用HH:MM格式格式化部分日期(两个日期之间的差异)。
为此,我汇总了以下逻辑:
LTRIM(TO_CHAR(TRUNC((DATE_DIFFERENCE) * 24),'00')) || ':' || LTRIM(TO_CHAR(MOD(ROUND((DATE_DIFFERENCE)*24*60),60),'00'))
我需要将这个逻辑应用于多个区间,因此使用函数键入DRY是很好的。
有没有办法在SQL语句中嵌入这个逻辑(可能使用Java),而不必求助于创建Oracle函数?
**编辑**
DATE_DIFFERENCE可以是负数且超过24小时。我想包括标志,如果是负数,但也代表小时和分钟的差异,即使DATE_DIFFERENCE是> 24小时。
答案 0 :(得分:2)
从查询中访问的Java函数比SQL函数要多得多,所以我不完全确定你的意思。当您混合使用SQL和PL / SQL上下文时,不能使用查询声明函数。
您的转化看起来不必要地复杂化;你可以这样做:
substr(numtodsinterval(date_difference, 'DAY'), 12, 5)
numtodsinterval
function获取您的日期差异并将其转换为区间数据类型,substr
获取涵盖小时和分钟的部分。
它的行为略有不同,因为它会截断而不是围绕分钟:
with tmp as (
select to_date('2013-04-11 13:17:15', 'YYYY-MM-DD HH24:MI:SS')
- to_date('2013-04-11 12:57:38', 'YYYY-MM-DD HH24:MI:SS')
as date_difference
from dual
union all
select to_date('2013-04-11 11:11:35', 'YYYY-MM-DD HH24:MI:SS')
- to_date('2013-04-10 22:40:45', 'YYYY-MM-DD HH24:MI:SS')
from dual
union all
select to_date('2013-04-11 00:59:59', 'YYYY-MM-DD HH24:MI:SS')
- to_date('2013-04-11 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
from dual
)
select LTRIM(TO_CHAR(TRUNC((DATE_DIFFERENCE) * 24),'00')) || ':' ||
LTRIM(TO_CHAR(MOD(ROUND((DATE_DIFFERENCE)*24*60),60),'00')),
substr(numtodsinterval(date_difference, 'DAY'), 12, 5)
from tmp;
LTRIM(T SUBSTR(NUMTODSINTERV
------- --------------------
00:20 00:19
12:31 12:30
00:00 00:59
这些的完整间隔是:
NUMTODSINTERVAL(DATE_DIFFERENCE,'DAY')
---------------------------------------------------------------------------
+000000000 00:19:37.000000000
+000000000 12:30:50.000000000
+000000000 00:59:59.000000000
很明显,第一个会转到00:20
,但会截断为00:19
。正如Egor Skriptunoff在评论中指出的那样,你对第三个的计算给出了一个不正确的答案,这就是我现在把它包括在内的原因。
这会在几分钟内完成,但会更长一点:
to_char(round(date '2001-01-01' + date_difference, 'MI'), 'HH24:MI')
我使用date '2001-01-01'
的文字中使用的实际日期并不重要,可以是任何一天,例如,您可以使用trunc(sysdate)
。它只允许您将差异转换回DATE
对象,然后您可以使用内置的round(date)
function。为了比较:
with tmp as (...)
select LTRIM(TO_CHAR(TRUNC((DATE_DIFFERENCE) * 24),'00')) || ':' ||
LTRIM(TO_CHAR(MOD(ROUND((DATE_DIFFERENCE)*24*60),60),'00')),
substr(numtodsinterval(date_difference, 'DAY'), 12, 5),
to_char(trunc(date '2001-01-01' + date_difference, 'MI'), 'HH24:MI'),
to_char(round(date '2001-01-01' + date_difference, 'MI'), 'HH24:MI')
from tmp;
LTRIM(T SUBSTR(NUMTODSINTERV TO_CH TO_CH
------- -------------------- ----- -----
00:20 00:19 00:19 00:20
12:31 12:30 12:30 12:31
00:00 00:59 00:59 01:00
这些实际上都没有给你你想要的东西,一个嵌入式的ad hoc函数,但至少如果逻辑更清晰,那么重用它可能不是那么担心。尽管如此,将它包装在SQL函数中仍然可能不是一个糟糕的选择。