Разделение и последовательное в SQL - PullRequest
0 голосов
/ 18 февраля 2020

коллег по укладке

У меня есть такой набор данных:

+---------+------+--------+
| user_id | date | metric |
+---------+------+--------+
|       1 |    1 |      1 |
|       1 |    2 |      1 |
|       1 |    3 |      1 |
|       2 |    1 |      1 |
|       2 |    2 |      1 |
|       2 |    3 |      0 |
|       2 |    4 |      1 |
+---------+------+--------+

Я хочу отметить тех клиентов, у которых есть 3 последовательных "1" в столбце metri c , У меня есть решение, как показано ниже.

select      distinct user_id
from        (
             select      user_id
                         ,metric +
                          ifnull( lag(metric, 1) OVER (PARTITION BY user_id ORDER BY date), 0 ) +
                          ifnull( lag(metric, 2) OVER (PARTITION BY user_id ORDER BY date), 0 )
                          as consecutive_3
             from        df
             ) b
where       consecutive_3 = 3

Пока оно работает, оно не масштабируется. Как можно себе представить, как бы выглядел приведенный выше запрос, если бы я искал последовательные 50. Могу ли я спросить, есть ли масштабируемое решение? Подойдет любое облако SQL. Спасибо.

1 Ответ

1 голос
/ 18 февраля 2020

Если вы хотите только таких пользователей, вы можете использовать sum(). Предполагая, что metric - это всего лишь 0 или 1:

select user_id,
       (case when max(metric_3) = 3 then 1 else 0 end) as flag_3
from (select df.*,
             sum(metric) over (partition by user_id
                               order by date
                               rows between 2 preceding and current row
                              ) as metric_3
      from df
     ) df
group by user_id;

С помощью предложения управления окнами вы можете легко расширить до столько смежных 1, сколько вам нужно.

...