简体   繁体   中英

Oracle group by row value

I have a table of the following format:

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

EDIT: There is also aditional timestamp column.

I would like to get the following output. In other words I want to get the sum grouped by users and actions

 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

What is te best way to acomplish this ?

With the timestamp information, you can do:

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
;

This gives:

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

Explanations :

  • PERSON is used instead of USER which is a reserved word in Oracle SQL (idem for SUM )
  • I used regular expressions to get the action and quantity
  • the hardest part is to associate the user to the lines that don't have any (with message like A1 4 ). This is why I use a dense_rank : to make it quick, this means "give me for the current line the latest message like User % with a timestamp before the one of the current line"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM