вопросы по функциям агрегации - PullRequest
2 голосов
/ 24 мая 2019

Я пытаюсь свернуть / агрегировать записи, но не могу найти решение с помощью функций агрегации оракула. ​​

Я играл с LAG, COLLECT, RANK, но пока не нашел решения.

У меня есть следующая таблица, и мне нужно получить последние 5 комментариев пользователей за последние два действия пользователя.

Пример ниже, два последних действия - Действие2 и Действие3.

date     | user_id | user_action | user_comment
---------+---------+-------------+-------------
5/1/2019 | USER3   | OPEN        | COMMENT0
5/1/2019 | USER1   | ACTION1     | COMMENT1
5/2/2019 | USER2   | OPEN        | COMMENT2
5/3/2019 | USER2   | ACTION2     | COMMENT3
5/4/2019 | USER3   | OPEN        | COMMENT4
5/5/2019 | USER3   | OPEN        | COMMENT5
5/5/2019 | USER4   | OPEN        | COMMENT6
5/6/2019 | USER3   | OPEN        | COMMENT7
5/7/2019 | USER3   | OPEN        | COMMENT8
5/8/2019 | USER3   | OPEN        | COMMENT9
5/9/2019 | USER3   | ACTION3     | COMMENT10

Дело в том, что действие User4 не должно быть включено.

Комментарий0 не должен быть включен, поскольку он не находится между Action2 и action3, даже если это тот же пользователь, что и Action3.

Ожидаемые результаты:

user_id | action  | comments
--------+---------+--------------------------------------------------
USER3   | ACTION3 | COMMENT10//COMMENT9//COMMENT8//COMMENT7//COMMENT5
USER2   | ACTION2 | COMMENT3//COMMENT2

Кто-нибудь может дать какие-нибудь советы?

1 Ответ

0 голосов
/ 26 мая 2019

Следующий запрос может потребовать некоторых настроек.Тем не менее, это может дать вам отправную точку для поиска решения, которое соответствует вашим требованиям.Идеи / шаги: {1} Пронумеруйте все записи для конкретного пользователя с помощью ROW_NUMBER ().{2} Найти последние 2 действия.{3} объедините 2 набора результатов, выберите последние 5 записей и поместите комментарии в одну строку, используя GROUP BY и LISTAGG ().

select 
  UA.userid, UA.useraction
, listagg( R.usercomment, '//' ) within group ( order by R.date_ desc ) --{3}
  as comments
from (
  select -- {1}
    date_, userid, useraction, usercomment
  , row_number() over ( partition by userid order by date_ desc ) rownum_
  from useractions
) R join ( -- {3}
  select userid, useraction -- {2}
  from (
    select date_, userid, useraction
    , row_number() over ( order by date_ desc ) rownum2_
    from useractions 
    where useraction like 'ACTION%' 
  )  
  where rownum2_ <= 2 
) UA on R.userid = UA.userid      -- {3} join
where R.rownum_ between 1 and 5   -- {3} we only the last 5 entries
group by UA.userid, UA.useraction -- {3}
order by userid desc
;

-- result
USERID  USERACTION  COMMENTS                                           
USER3   ACTION3     COMMENT10//COMMENT9//COMMENT8//COMMENT7//COMMENT5  
USER2   ACTION2     COMMENT3//COMMENT2

DBfiddle

...