Условное опережение / запаздывание без гарантии последовательности - PullRequest
1 голос
/ 27 мая 2020

Как можно записать условное опережение / отставание, когда предыдущее или последующее опережение / отставание не гарантированно удовлетворяет определенному условию? В моем случае я смотрю на трафик веб-сайта c.

Образцы данных (Prior_path и Prior_event - это целевые поля, для которых у меня возникают проблемы с доступом к Prior_event с учетом моих условий)

+-----------+-----+-------+---------------------------------------+-------+------------------------------------+-------------+
| sessionid | hit | type  |                 path                  | event |             prior_path             | prior_event |
+-----------+-----+-------+---------------------------------------+-------+------------------------------------+-------------+
|      1001 |   1 | event | www.stackoverflow.com                 | hover |                                    |             |
|      1001 |   2 | page  | www.stackoverflow.com                 |       |                                    | hover       |
|      1001 |   3 | event | www.stackoverflow.com                 | load  |                                    |             |
|      1001 |   4 | event | www.stackoverflow.com                 | blur  |                                    | load        |
|      1001 |   5 | event | www.stackoverflow.com                 | click |                                    | blur        |
|      1001 |   6 | page  | www.stackoverflow.com/post/10         |       | www.stackoverflow.com              | click       |
|      1001 |   7 | event | www.stackoverflow.com/post/10#details | offer |                                    |             |
|      1001 |   8 | page  | www.stackoverflow.com/post/confirm    |       | www.stackoverflow.com/post/10      | offer       |
|      1001 |   9 | page  | www.stackoverflow.com/questions/10    |       | www.stackoverflow.com/post/confirm | offer       |
|      1001 |  10 | event | www.stackoverflow.com/questions/10    | exit  |                                    |             |
+-----------+-----+-------+---------------------------------------+-------+------------------------------------+-------------+

Prior_path: последний путь, где type = page только для типов обращений страницы prior_event: последнее событие, где type = event для всех типов обращений

Обратите внимание, для обращений 8 и 9 событие «предложение» повторяется, потому что те, которые привели к этим страницам.

prior_path кажется простым, как и я

SELECT LAG(path) OVER (PARTITION BY sessionid, type ORDER BY hit) FROM my_table

, но я не уверен, как получить prior_event.

Ответы [ 2 ]

1 голос
/ 27 мая 2020

У вас уже есть правильное выражение для prior_path. Вам просто нужно обернуть его условным выражением.

Что касается prior_event, это действительно немного сложнее. Я бы предложил следующий подход:

  • для событий, мы можем просто использовать lag()

  • для страниц, вариант - использовать некоторые Техника промежутков и островов: сначала определите группы с условной суммой, которая увеличивается каждый раз, когда встречается событие, а затем используйте first_value():

Это должно делать то, что вы хотите:

select  
    t.*,
    case when type = 'page'
        then lag(path) over(partition by sessionid, type  order by hit)
    end prior_path,
    case type 
        when 'page'
            then first_value(event) over(partition by sessionid, grp order by hit)
        when 'event' 
            then lag(event) over(partition by sessionid order by hit)
        end prior_event
from (
    select 
        t.*,
        sum(case when type = 'event' then 1 else 0 end) 
            over(partition by sessionid order by hit) grp
    from mytable t
) t

Демо на DB Fiddle (из-за отсутствия скрипта hive в дикой природе я использовал Postgres - но это также будет работать на Hive ):

sessionid | hit | type  | path                                  | event | grp | prior_path                         | prior_event
--------: | --: | :---- | :------------------------------------ | :---- | --: | :--------------------------------- | :----------
     1001 |   1 | event | www.stackoverflow.com                 | hover |   1 | <em>null</em>                               | <em>null</em>       
     1001 |   2 | page  | www.stackoverflow.com                 | <em>null</em>  |   1 | <em>null</em>                               | hover      
     1001 |   3 | event | www.stackoverflow.com                 | load  |   2 | <em>null</em>                               | <em>null</em>       
     1001 |   4 | event | www.stackoverflow.com                 | blur  |   3 | <em>null</em>                               | load       
     1001 |   5 | event | www.stackoverflow.com                 | click |   4 | <em>null</em>                               | blur       
     1001 |   6 | page  | www.stackoverflow.com/post/10         | <em>null</em>  |   4 | www.stackoverflow.com              | click      
     1001 |   7 | event | www.stackoverflow.com/post/10#details | offer |   5 | <em>null</em>                               | <em>null</em>       
     1001 |   8 | page  | www.stackoverflow.com/post/confirm    | <em>null</em>  |   5 | www.stackoverflow.com/post/10      | offer      
     1001 |   9 | page  | www.stackoverflow.com/questions/10    | <em>null</em>  |   5 | www.stackoverflow.com/post/confirm | offer      
     1001 |  10 | event | www.stackoverflow.com/questions/10    | exit  |   6 | <em>null</em>                               | <em>null</em>       
0 голосов
/ 27 мая 2020

Думаю, вам просто нужно lag() и несколько условных логарифмов c:

select . . .,
       (case when type = 'page'
             then lag(path) over (partition by sessionid, type order by hit)
        end) as prior_path,
       lag(event) over (partition by sessionid order by hit) as prior_event
from my_table;
...