oracle中同一列中的时间戳之间的差异

时间:2017-03-24 10:55:38

标签: sql oracle

我在call_event表中有以下记录;

EVENT_ID   TIMESTAMP             EVENT   
---------  -------------------   ------
9000       03/27/2017 18.00.39   Call Start
9000       03/27/2017 18.08.44   Call END
9001       03/28/2017 14.30.27   Call Start
9001       03/28/2017 15.02.56   Call END

我应该在oracle中写什么查询来获得以下结果

EVENT_ID   TIMESTAMP             EVENT      Call Duration
---------  -------------------   ------     -------------   
9000       03/27/2017 18:00:39   Call Start  00:09:23
9000       03/27/2017 18:08:44   Call END    00:09:23
9001       03/28/2017 14.30.27   Call Start  00:33:29
9001       03/28/2017 15.02.56   Call END    00:33:29

4 个答案:

答案 0 :(得分:0)

为什么一次通话需要两行?我倾向于转动数据:

select event_id, min(timestamp) as call_start_ts, max(timestamp) as call_end_ts,
       max(timestamp) - min(timestamp) as duration
from t
group by event_id;

如果timestamp列确实是时间戳,那么duration将是interval。以上假设呼叫在结束前开始。

话虽如此,如果你想要单独的行::

,你可以用窗口函数做同样的事情
select event_id, min(timestamp) as call_start_ts, max(timestamp) as call_end_ts,
       (max(timestamp) over (partition by event_id) -
        min(timestamp) over (partition by event_id)
       ) as duration
from t
group by event_id;

答案 1 :(得分:0)

这可以帮到你吗

SELECT A.EVENT_ID, A.TIMESTAMP, A.EVENT, B.TIMESTAMP AS TIMESTAMP_END, B.EVENT AS EVENT_END, B.TIMESTAMP - A.TIMESTAMP AS DURATION
FROM CALL_EVENT A 
INNER JOIN  CALL_EVENT B ON A.EVENT_ID = B.EVENT_ID 
WHERE A.EVENT = 'Call Start'
AND B.EVENT = 'Call END'

答案 2 :(得分:0)

最棘手的部分是日期时间间隔的格式化,因为oracle中没有类似于TO_CHAR(...)系列的收缩包装函数:

SELECT event_id
     ,           to_char(extract(HOUR   FROM delta), 'fm00')
       || ':' || to_char(extract(MINUTE FROM delta), 'fm00')
       || ':' || to_char(extract(SECOND FROM delta), 'fm00') duration
  FROM (
            SELECT event_id
                 , max(ts) - min(ts) delta
              FROM events
          GROUP BY event_id
       )
     ;

变体处理建模为DATE列的时间戳:

SELECT event_id
     ,           to_char(extract(HOUR   FROM delta), 'fm00')
       || ':' || to_char(extract(MINUTE FROM delta), 'fm00')
       || ':' || to_char(extract(SECOND FROM delta), 'fm00') duration
  FROM (
            SELECT event_id
                 , numtodsinterval ( max(ts) - min(ts), 'DAY' ) delta
              FROM events
          GROUP BY event_id
       )
     ;

在oracle 12c1上测试。

现金: 从this SO answer

获取的间隔格式

答案 3 :(得分:0)

Oracle安装程序

CREATE TABLE call_event ( EVENT_ID, "TIMESTAMP", EVENT ) AS
SELECT 9000, TIMESTAMP '2017-03-27 18:00:39', 'Call Start' FROM DUAL UNION ALL
SELECT 9000, TIMESTAMP '2017-03/27 18:08:44', 'Call END' FROM DUAL UNION ALL
SELECT 9001, TIMESTAMP '2017-03-28 14:30:27', 'Call Start' FROM DUAL UNION ALL
SELECT 9001, TIMESTAMP '2017-03-28 15:02:56', 'Call END' FROM DUAL;

<强>查询

SELECT t.*,
       MAX( "TIMESTAMP" ) OVER ( PARTITION BY EVENT_ID )
         - MIN( "TIMESTAMP" ) OVER ( PARTITION BY EVENT_ID )
         AS "Call Duration"
FROM   call_event;

<强>输出

EVENT_ID TIMESTAMP           EVENT      Call Duration
-------- ------------------- ---------- -------------------
    9000 2017-03-27 18:00:39 Call Start +00 00:08:05.000000
    9000 2017-03-27 18:08:44 Call END   +00 00:08:05.000000
    9001 2017-03-28 14:30:27 Call Start +00 00:32:29.000000
    9001 2017-03-28 15:02:56 Call Start +00 00:32:29.000000