Получить номер строки для последовательного статуса и сброс при изменении - PullRequest
0 голосов
/ 18 октября 2018

Итак, я хочу, чтобы пользователи могли отслеживать количество последовательных входов за недели.Я попытался row_number () Over (разделение по государственному заказу по неделям), но row_numbers не сбрасываются при изменении состояния.Вот пример таблицы.

user_id |     week     | state  
--------+--------------+-------
1       | 2018-01-01   | Active  
1       | 2018-01-08   | Inactive  
1       | 2018-01-15   | Inactive  
1       | 2018-01-22   | Active  
1       | 2018-01-29   | Active  
2       | 2018-01-01   | Inactive  
2       | 2018-01-08   | Active  
2       | 2018-01-15   | Inactive  
2       | 2018-01-22   | Active  
2       | 2018-01-29   | Active 

Я хочу, чтобы вывод выглядел так:

user_id |     week     |  state   | streak
--------+--------------+----------+---------
1000    | 2018-01-01   | Active   |  1
1000    | 2018-01-08   | Inactive |  1
1000    | 2018-01-15   | Inactive |  2
1000    | 2018-01-22   | Active   |  1
1000    | 2018-01-29   | Active   |  2
2000    | 2018-01-01   | Inactive |  1
2000    | 2018-01-08   | Active   |  1
2000    | 2018-01-15   | Inactive |  1
2000    | 2018-01-22   | Active   |  1
2000    | 2018-01-29   | Active   |  2

Это мой текущий запрос:

SELECT
    week,
    user_id,
    state,
    row_number()
    OVER(PARTITION BY user_id, state
      order by user_id, week) AS streak
  FROM
    t.data_table
  GROUP BY 1,2,3
  order by week;

Мой вывод в настоящее время выглядит следующим образом:

user_id |     week     |  state   | streak
--------+--------------+----------+---------
1000    | 2018-01-01   | Active   |  1
1000    | 2018-01-08   | Inactive |  1
1000    | 2018-01-15   | Inactive |  2
1000    | 2018-01-22   | Active   |  2
1000    | 2018-01-29   | Active   |  3
2000    | 2018-01-01   | Inactive |  1
2000    | 2018-01-08   | Active   |  1
2000    | 2018-01-15   | Inactive |  2
2000    | 2018-01-22   | Active   |  2
2000    | 2018-01-29   | Active   |  3

Любые предложения здесь будут полезны.

1 Ответ

0 голосов
/ 18 октября 2018

Это проблема пробелов и островов.Стратегия состоит в том, чтобы определить группы строк с одинаковым статусом, а затем использовать row_number() для их перечисления.

В одном методе используется разница номеров строк:

select t.*,
       row_number() over (partition by user_id, status, seqnum - seqnum_s order by week) as streak
from (select t.*,
             row_number() over (partition by user_id order by week) as seqnum,
             row_number() over (partition by user_id, status order by week) as seqnum_s
      from t
     ) t;

Немного сложно объяснить, как это работает.Если вы посмотрите на результаты подзапроса, вы увидите, как разность номеров строк определяет каждую из групп, где статус одинаковый.

...