Oracle逐行值

时间:2014-06-06 07:52:48

标签: sql oracle select

我有一个以下格式的表格:

Message ID Message
 1          User 1
 2          A1 4
 3          A2 6
 4          A3 5
 5          A4 7
 1          User 2
 2          A1 3
 3          A2 2
 4          A3 6
 5          A4 2
 1          User 1
 2          A1 4
 3          A2 6
 4          A3 5
 5          A4 7
 1          User 2
 2          A1 3
 3          A2 2
 4          A3 6
 5          A4 2

编辑:还有aditional timestamp列。

我想获得以下输出。换句话说,我希望按用户和操作分组总和

 User   Action Action sum
 User 1 A1       8
 User 1 A2      12
 User 1 A3      10
 User 1 A4      14
 User 2 A1       6
 User 2 A2       4
 User 2 A3      12
 User 2 A4       4

实现这个目标的最佳方式是什么?

1 个答案:

答案 0 :(得分:1)

使用时间戳信息,您可以执行以下操作:

with w as
(
  select t.*,
         regexp_substr(t.message, 'A\d+') action, -- Get action "An", where n is a number
         regexp_substr(t.message, ' (\d+)') quantity, -- Get quantity after blank
         (select max(t2.message) keep (dense_rank last order by t2.timestamp) u
          from your_table t2
          where t2.message like 'User %'
            and t2.timestamp <= t1.timestamp) person
  from your_table t1
  order by t1.timestamp
)
select w.person, w.action, sum(to_number(w.quantity)) sum_quantity
from w
where w.action is not null
group by w.person, w.action
order by w.person, w.action
;

这给出了:

PERSON  ACTION  SUM_QUANTITY
User 1  A1  8
User 1  A2  12
User 1  A3  10
User 1  A4  14
User 2  A1  6
User 2  A2  4
User 2  A3  12
User 2  A4  4

说明:

    使用
  • PERSON代替USER,这是Oracle SQL中的保留字(SUM的同义词)
  • 我使用正则表达式来获取动作和数量
  • 最难的部分是将用户与不具有任何内容的行相关联(使用A1 4之类的消息)。这就是为什么我使用dense_rank:快速启用它,这意味着&#34;为当前行提供最新的message,如User %,其中一个时间戳位于其中一个之前当前行&#34;