Oracle 11g聚合行

时间:2013-06-17 10:41:17

标签: sql oracle oracle11g

我试图找出在oracle中聚合多行的最佳方法。我们有一个表,用于记录关键用户事件,因为它们经历了流程。我们有以下表格结构:

User Id    Event Code    Event Timestamp
1            START       17/06/2013 11:00
1            END         17/06/2013 11:05
2            START       16/06/2013 11:00
2            END         16/06/2013 11:05

我们希望从我们的数据库中获取一份报告,该报告将以下列格式捕获用户的某些事件代码的时间戳:

User ID     Start Date/Time     End Date/Time
1           17/06/2013 11:00    17/06/2013 11:05
2           16/06/2013 11:00    16/06/2013 11:05

我不确定如何在SQL中做到这一点,不要介意最好的方法,所以任何建议都会受到赞赏。

4 个答案:

答案 0 :(得分:3)

假设您的表格是您所描述的,可以使用简单的PIVOT完成。

假设:

create table event ( id number, event_code varchar2(5), tstamp date );

insert into event values (1, 'START', to_date('17/06/2013 11:00','DD/MM/YYYY HH24:MI'));
insert into event values (1, 'END', to_date('17/06/2013 11:05','DD/MM/YYYY HH24:MI'));
insert into event values (2, 'START', to_date('16/06/2013 11:00','DD/MM/YYYY HH24:MI'));
insert into event values (2, 'END', to_date('16/06/2013 11:05','DD/MM/YYYY HH24:MI'));

查询将是:

select *
  from event
 pivot ( max(tstamp) for event_code in ('START','END') )

Here's a SQL Fiddle

答案 1 :(得分:0)

如果真实数据就像您显示的那样简单 - 那么只需在查询中引用同一个表两次 - 一次检索起始数据,一次结束日期......类似于:

select user_id, s.event_tm, as start_time, e.event_tm as end_time
from 
( select user_id, event_tm from mytable where event_cd = 'START' ) s
,( select user_id, event_tm from mytable where event_cd = 'END' ) e
where s.user_id = e.user_id
工作小提琴 http://www.sqlfiddle.com/#!4/d141c/7

答案 2 :(得分:0)

假设每个用户只有一个事件:

SELECT
Userid
,MAX(CASE WHEN flag = 'START' THEN dt END) AS started
,MAX(CASE WHEN flag = 'END' THEN dt END) AS Ended
FROM
(
SELECT 1 as userid,            'START' as flag   ,    '17/06/2013 11:00' as dt FROM DUAL
UNION ALL SELECT 1,            'END' as flag    ,   '17/06/2013 11:05' As dt FROM DUAL
UNION ALL SELECT 2,            'START'     as flag , '16/06/2013 11:00' As dt FROM DUAL
UNION ALL SELECT 2,            'END'        as flag,  '16/06/2013 11:05' As dt FROM DUAL
) a
GROUP BY userid

答案 3 :(得分:0)

如果事件代码值一致并且在“开始”和“结束”之间有所不同,那么您可以将表格连接到自身并过滤结果:

select t1.id as "User ID", t1."Event Timestamp" as "Start DateTime", t2."Event Timestamp" as "Start DateTime" 
from your_table t1, your_table t2 
where t1.id = t2.id and t1."Event Code" = 'START' and t2."Event Code" = 'END'