我试图找出在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中做到这一点,不要介意最好的方法,所以任何建议都会受到赞赏。
答案 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') )
答案 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'