格式化使用提取所花费的总时间

时间:2015-12-10 18:22:11

标签: sql oracle oracle11g

我可以接受任何建议,只要我得到类似帖子底部输出的内容,TIA!

我可以从这个sql小提琴获得一些帮助:http://sqlfiddle.com/#!4/c51c5/1

SCHEMA

create table history(
      clockingGroup varchar2(5)
    , startTime timestamp
    , endTime timestamp);

insert into history
  (clockingGroup, startTime, endTime)
 values
  ('grp1', '01-dec-2015 1:00:00.000000', '01-dec-2015 1:10:10.000000');
insert into history
  (clockingGroup, startTime, endTime)
 values
  ('grp2', '01-dec-2015 1:10:10.000000', '01-dec-2015 1:20:20.000000');
insert into history
  (clockingGroup, startTime, endTime)
values
  ('grp1', '01-dec-2015 1:20:20.000000', '01-dec-2015 1:30:35.000000');
insert into history
  (clockingGroup, startTime, endTime)
values
  ('grp3', '01-dec-2015 1:30:35.000000', '01-dec-2015 1:35:00.000000');

SQL

select 
     extract(hour from (sum(cast(endTime as date) - cast(startTime as date)))) || ' Hours ' 
  || extract(minute from (sum(cast(endTime as date) - cast(startTime as date)))) || ' Minutes ' 
  || extract(second from (sum(cast(endTime as date) - cast(startTime as date)))) || ' Seconds' 

  as totalTime
  , clockingGroup
from 
  history
group by 
  clockingGroup

当前错误     ORA-30076: invalid extract field for extract source

我想要的输出是:

clockingGroup | totalTime    
grp1          | 0 Hours 20 Minutes 25 Seconds
grp2          | 0 Hours 10 Minutes 10 Seconds
grp3          | 0 Hours 4 Minutes 25 Seconds 

1 个答案:

答案 0 :(得分:1)

您正在以错误的顺序使用内置插件。您的原始查询会将时间戳转换为日期。当您从彼此中减去日期时,您会得到一个数字。 在下面的查询中,它从时间戳中减去时间戳,产生INTERVAL。您无法从数字中提取小时数,但可以从INTERVAL中提取。

SELECT clockingGroup.
SUM(extract(DAY FROM endtime-starttime))    ||' '|| 
SUM(extract(HOUR FROM endtime-starttime))   ||' '|| 
SUM(extract(MINUTE FROM endtime-starttime)) ||' '|| 
SUM(extract(SECOND FROM endtime-starttime)) AS TOTALTIME,

from 
  history
group by 
  clockingGroup

我看到你使用numtodsinterval添加了另一种方法。您仍在将时间戳转换为您不需要精确的日期。

这个查询比较复杂,因为我尝试并显示你如何消除差异并将所有间隔计为秒,将它们相加然后将它分成几小时/分钟/秒

SELECT CLOCKINGGROUP, TO_CHAR(TRUNC(SUMTOTALSECONDS/3600),'FM9900') || ' Hours ' ||
    TO_CHAR(TRUNC(MOD(SUMTOTALSECONDS,3600)/60),'FM00') || ' Minutes ' ||
    TO_CHAR(MOD(SUMTOTALSECONDS,60),'FM00') || ' Seconds'
FROM(
SELECT clockinggroup, TRUNC(SUM(TOTALSECONDS),0) AS SUMTOTALSECONDS
FROM (
SELECT clockinggroup,
EXTRACT (DAY FROM (EndTime-StartTime))*24*60*60 +
EXTRACT (HOUR FROM (EndTime-StartTime))*60*60 +
EXTRACT (MINUTE FROM (EndTime-StartTime))*60 + 
EXTRACT (SECOND FROM (EndTime-StartTime))/60 AS TOTALSECONDS  
FROM history)
group by 
clockingGroup)
ORDER BY 1;