Группировать и ранжировать последовательные значения по условию в SQL - PullRequest
0 голосов
/ 11 января 2019

У меня есть таблица mytable, к которой я хотел бы добавить два дополнительных столбца

Моя цель - сгруппировать по user_id и mobile_id только , где существует непрерывная последовательность значений, где difftime > - 600. Последовательность должна быть последовательной в created_at (отметка времени), и ей должен быть присвоен ранг, начиная снова, если это один и тот же пользователь и мобильный идентификатор, но встречается difftime <- 600. Каждой отдельной группе будет назначено инкрементное значение. Например: </p>

> mytable
            created_at user_id mobile_id   status difftime
1  2019-01-02 22:01:38 1227604     68409 finished      \\N
2  2019-01-03 04:08:29 1227604     68409 finished     -366
3  2019-01-03 15:16:38 1227604     68409  timeout     -668
4  2019-01-04 00:34:40 1227604     68409   failed     -558
5  2019-01-04 00:27:37 1227605     68453   failed      \\N
6  2019-01-04 00:35:56 1227605     68453 finished       -8
7  2019-01-04 01:39:52 1227605     68453 finished      -63
8  2019-01-04 02:05:53 1227605     68453  timeout      -26
9  2019-01-04 02:17:17 1227605     68453  timeout      -11
10 2019-01-04 16:51:39 1227605     68453  timeout     -874

Создает вывод

> output
            created_at user_id mobile_id   status difftime group rank
1  2019-01-02 22:01:38 1227604     68409 finished      \\N    NA   NA
2  2019-01-03 04:08:29 1227604     68409 finished     -366     1    1
3  2019-01-03 15:16:38 1227604     68409  timeout     -668    NA   NA
4  2019-01-04 00:34:40 1227604     68409   failed     -558     2    1
5  2019-01-04 00:27:37 1227605     68453   failed      \\N    NA   NA
6  2019-01-04 00:35:56 1227605     68453 finished       -8     3    1
7  2019-01-04 01:39:52 1227605     68453 finished      -63     3    2
8  2019-01-04 02:05:53 1227605     68453  timeout      -26     3    3
9  2019-01-04 02:17:17 1227605     68453  timeout      -11     3    4
10 2019-01-04 16:51:39 1227605     68453  timeout     -874    NA   NA

Когда я просто пытаюсь присвоить звание, следующий запрос выдает ошибку: WHERE clause cannot contain aggregations, window functions or grouping operations

Несмотря на то, что я использую Presto SQL, любое решение SQL здесь будет полезно, чтобы помочь подумать о том, как реструктурировать запрос

SELECT 
    *,
    ROW_NUMBER() OVER (PARTITION BY user_id, mobile_id ORDER BY created_at) as rank
    from mytable
    WHERE DATE_DIFF('minute', created_at, lag(created_at) OVER (PARTITION BY user_id, mobile_id ORDER BY user_id, created_at)) > -600
    ORDER BY user_id, mobile_id, created_at

1 Ответ

0 голосов
/ 11 января 2019

Чтобы определить группы, сделайте кумулятивную сумму значений, которые являются «недействительными». Затем используйте dense_rank() для присвоения значения.

Я понятия не имею, что ваш запрос имеет отношение к вашей проблеме, но логика будет такой:

select t.*, grp,
       (case when difftime > -600
             then row_number() over (partition by user_id, mobile_id order by created_at)
        end) as rank
from (select t.*,
             dense_rank() over (partition by user_id, mobile_id order by grouping) as grp
      from (select t.*,
                   sum(case when difftime > -600 then 1 else 0 end) over (partition by user_id, mobile_id order by created_at) as grouping
            from t
            ) t
     ) t
...