获取特定持续时间的秒数

时间:2015-12-29 13:54:24

标签: sql oracle datetime

我的表中包含有关通话的信息​​,每个通话都有start dateend date,其DATE类型为 YYYY:MM:DD HH:MI:SS 格式。

如何获得以下内容:

start date与{{1}之间的 00:00:00 07:30:00 范围内的1-秒数},以及超出给定范围的秒数( 00:00:00 07:30:00 )。

end datestart date之间的星期五天的秒数。

3 个答案:

答案 0 :(得分:1)

我尝试使用分层子查询为每个调用生成天数和函数greatestleast

SQLFiddle

with t as (
  select id, sd, ed, trunc(sd)+level-1 dt
    from calls 
    connect by trunc(sd)+level-1<=trunc(ed) 
      and prior dbms_random.value is not null and prior id = id)
select id, sum(sec) sec, sum(fri) fri, sum(mrn) mrn, sum(sec)-sum(mrn) rest
  from (
    select id, (least(ed, dt+1)-greatest(sd, dt))*24*60*60 sec,
           case when trunc(dt) - trunc(dt, 'iw') = 4 
                then (least(dt+1, ed) - greatest(dt, sd)) * 24*60*60 end fri,
           (least(dt+7.5/24, ed) - greatest(dt, sd)) * 24*60*60 mrn
      from t )
  group by id

查询“星期五”的版本 - “非星期五早晨” - “非星期五休息日”输出(在评论中准确):

with cte as (
  select id, sd, ed, trunc(sd)+level-1 dt from calls
    connect by level <= trunc(ed)-trunc(sd) + 1 
      and prior dbms_random.value is not null and prior id = id )
select id, max(sd) start_time, max(ed) end_time, 
       sum(sec) all_seconds, sum(fri) fridays, sum(mrn) mornings,
       sum(sec) - sum(fri) - sum(mrn) rest
  from (
    select id, sd, ed, dt, (least(ed, dt+1) - greatest(sd, dt))*24*60*60 sec,
        case when dt - trunc(dt, 'iw') = 4 
             then (least(ed, dt+1) - greatest(sd, dt))*24*60*60 else 0 end fri,
        case when dt - trunc(dt, 'iw') <> 4 and dt+7.5/24 > sd 
             then (least(dt+7.5/24, ed) - greatest(sd, dt))*24*60*60 
             else 0 end mrn
      from cte )
  group by id order by id

示例数据和输出:

create table calls (id number(3), sd date, ed date);
insert into calls values (1, timestamp '2015-12-25 07:29:00', timestamp '2015-12-25 07:31:00');
insert into calls values (2, timestamp '2015-12-24 01:00:00', timestamp '2015-12-26 23:12:42');
insert into calls values (3, timestamp '2015-12-24 23:58:00', timestamp '2015-12-25 00:01:00');
insert into calls values (4, timestamp '2015-12-24 07:00:00', timestamp '2015-12-25 00:01:00');

  ID START_TIME          END_TIME            ALL_SECONDS    FRIDAYS   MORNINGS       REST
---- ------------------- ------------------- ----------- ---------- ---------- ----------
   1 2015-12-25 07:29:00 2015-12-25 07:31:00         120        120          0          0
   2 2015-12-24 01:00:00 2015-12-26 23:12:42      252762      86400      50400     115962
   3 2015-12-24 23:58:00 2015-12-25 00:01:00         180         60          0        120
   4 2015-12-24 07:00:00 2015-12-25 00:01:00       61260         60       1800      59400

编辑:

答案 1 :(得分:0)

使用:

SELECT (end_date - start_date), ... FROM ...  

您获得了天数......

使用:

SELECT (end_date - start_date)*24, ... FROM ...  

你获得了小时数...

并且:用:

SELECT (end_date - start_date)*24*60*60, ... FROM ...  

你获得了秒数......

答案 2 :(得分:0)

这很好用,子句仅用于测试:

with a as(
select
TO_TIMESTAMP('122320158:00:00','MMDDYYYYHH:MI:SS') start_date,TO_TIMESTAMP('122320158:01:06','MMDDYYYYHH:MI:SS') end_date from dual
union all
select
TO_TIMESTAMP('112420152:00:00','MMDDYYYYHH:MI:SS') start_date,TO_TIMESTAMP('112420152:00:53','MMDDYYYYHH:MI:SS') end_date from dual
union all
select
TO_TIMESTAMP('102720157:31:00','MMDDYYYYHH:MI:SS') start_date,TO_TIMESTAMP('102720157:31:10','MMDDYYYYHH:MI:SS') end_date from dual
) -- until here, with clause just give sample data
select  'before7.30' range,sum(EXTRACT(minute FROM(end_date-start_date))*60+EXTRACT(hour FROM(end_date-start_date))*3600+EXTRACT(second FROM(end_date-start_date))) as seconds
from (
select * from a
)
where start_date < trunc(start_date)+(1/24)*7.5 -- start_date<7.30
union all
select  'after7.30' range,sum(EXTRACT(minute FROM(end_date-start_date))*60+EXTRACT(hour FROM(end_date-start_date))*3600+EXTRACT(second FROM(end_date-start_date))) as seconds
from (
select * from a
)
where start_date >= trunc(start_date)+(1/24)*7.5 -- start_date>=7.30

输出:

before7.30  53
after7.30   76

如果名为cdr_table的表只删除with子句:

select  'before7.30' range,sum(EXTRACT(minute FROM(end_date-start_date))*60+EXTRACT(hour FROM(end_date-start_date))*3600+EXTRACT(second FROM(end_date-start_date))) as seconds
from (
select * from cdr_table
)
where start_date < trunc(start_date)+(1/24)*7.5
union all
select  'after7.30' range,sum(EXTRACT(minute FROM(end_date-start_date))*60+EXTRACT(hour FROM(end_date-start_date))*3600+EXTRACT(second FROM(end_date-start_date))) as seconds
from (
select * from cdr_table
)
where start_date >= trunc(start_date)+(1/24)*7.5