【问题标题】:Oracle 11g Aggregating RowsOracle 11g 聚合行
【发布时间】:2013-06-17 18:56:03
【问题描述】:

我正在尝试找出在 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 中做到这一点,不要介意最好的方法,所以任何建议都将不胜感激。

【问题讨论】:

  • 用户 1 是否有多个开始或结束日期?
  • 我们将捕获的一次性事件。
  • 可能不是“最佳方式”:sqlfiddle.com/#!4/80803/2
  • 澄清一下,我们将在此查询中捕获一次性事件,但该表将包含许多其他非一次性事件。

标签: sql oracle oracle11g


【解决方案1】:

假设你的表是你描述的那样,这可以通过一个简单的 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

【讨论】:

  • 谢谢你,它就像一个魅力。我已经能够做到这一点,以满足我们确切的报告要求。
【解决方案2】:

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

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】:

    如果事件代码值是一致的,并且在“开始”和“结束”之间有所不同,那么您可以直接加入您的表格并过滤结果,如下所示:

    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' 
    

    【讨论】:

      【解决方案4】:

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

      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

      【讨论】:

        猜你喜欢
        • 2014-05-09
        • 2022-01-14
        • 2013-04-11
        • 2013-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-08
        • 1970-01-01
        相关资源
        最近更新 更多