我有一张有两DATE列END_TIME和的表格START_TIME。在此表上,我运行以下查询:
DATE
END_TIME
START_TIME
SELECT y.ID, TO_CHAR( TO_DATE('00:00:00', 'HH24:MI:SS') + (y.END_TIME - y.START_TIME) , 'HH24:MI:SS') AS RUNTIME, y.END_TIME - y.START_TIME AS RUNTIME2, TO_CHAR(y.START_TIME, 'DD-MON-YYYY HH24:MI:SS') AS START_TIME, TO_CHAR(y.END_TIME, 'DD-MON-YYYY HH24:MI:SS') AS END_TIME FROM mytable y;
结果是这两行:
ID | RUNTIME | RUNTIME2 | START_TIME | END_TIME ------------------------------------------------------------------------------------------------------ 1 | 04:26:17| 0.1849189814814814814814814814814814814815 | 30-JAN-2015 19:45:48| 31-JAN-2015 00:12:05 2 | 03:28:18| 1.14465277777777777777777777777777777778 | 06-FEB-2015 20:47:22| 08-FEB-2015 00:15:40
如您所见,ID 2运行时间大于24小时。我怎样才能改变我的查询,以便RUNTIME于ID 2将显示27:28:18呢?
ID 2
RUNTIME
27:28:18
您需要将时差分解成其组成的日,时,分和秒元素,将天数* 24与小时数相结合,然后将其重新组合在一起。
减去日期时,您会得到天数的差异,因此需要将小数部分转换为其他元素,可以使用trunc和mod的组合来完成;使用CTE使其更容易理解,并显示每个值及其自己的值,并组合成一个字符串:
with y as ( select id, end_time - start_time as runtime from mytable ) select id, runtime, trunc(runtime) as days, 24 * trunc(runtime) as day_hours, trunc(24 * mod(runtime, 1)) as hours, trunc(60 * mod(24 * (runtime), 1)) as minutes, trunc(60 * mod(24 * 60 * (runtime), 1)) as seconds, lpad(24 * trunc(runtime) + trunc(24 * mod(runtime, 1)), 2, '0') ||':'|| lpad(trunc(60 * mod(24 * (runtime), 1)), 2, '0') ||':'|| lpad(trunc(60 * mod(24 * 60 * (runtime), 1)), 2, '0') as runtime from y; ID RUNTIME DAYS DAY_HOURS HOURS MINUTES SECONDS RUNTIME ---------- ---------- ---------- ---------- ---------- ---------- ---------- -------- 1 .184918981 0 0 4 26 16 04:26:16 2 1.14465278 1 24 3 28 18 27:28:18
您还可以将日期转换为时间戳以进行计算,这将为您提供一个间隔类型,然后使用该extract函数来获取元素。原理是一样的:
extract
with y as ( select id, cast(end_time as timestamp) - cast (start_time as timestamp) as runtime from mytable ) select id, runtime, extract (day from runtime) as days, 24 * extract (day from runtime) as day_hours, extract (hour from runtime) as hours, extract (minute from runtime) as minutes, extract (second from runtime) as seconds, lpad(24 * extract (day from runtime) + extract (hour from runtime), 2, '0') ||':'|| lpad(extract (minute from runtime), 2, '0') ||':'|| lpad(extract (second from runtime), 2, '0') as runtime from y; ID RUNTIME DAYS DAY_HOURS HOURS MINUTES SECONDS RUNTIME ---------- ----------- ---------- ---------- ---------- ---------- ---------- -------- 1 0 4:26:17.0 0 0 4 26 17 04:26:17 2 1 3:28:18.0 1 24 3 28 18 27:28:18
或略有变化,从日期中获取差异,然后将其转换为间隔:
with y as ( select id, numtodsinterval(end_time - start_time, 'DAY') as runtime from mytable ) ...