SQL (Presto) - «сжимать» строки, когда диапазоны дат последовательны - PullRequest
1 голос
/ 24 января 2020

У меня есть эти данные (образец):

event_id    period_start    period_end  rating
100269      2/8/2016        6/30/2016   1
100269      6/30/2016       12/31/2016  1
100269      12/31/2016      6/30/2017   2
100269      6/30/2017       12/31/2017  2

Я бы хотел "сжать" строки, когда периоды (period_start, period_end) сразу последовательны И рейтинг тот же , Желаемый результат будет:

event_id    period_start    period_end  rating
100269      2/8/2016        12/31/2016  1
100269      12/31/2016      12/31/2017  2

Обратите внимание, что в этом наборе данных не все периоды являются непосредственно последовательными для некоторых event_id. Вот пример и желаемый результат:

event_id    period_start    period_end  rating
100300      2/8/2016        6/30/2016   1
100300      6/30/2016       12/31/2016  1
100300      6/30/2017       12/31/2017  1

Желаемый результат:

event_id    period_start    period_end  rating
100300      2/8/2016        12/31/2016  1
100300      6/30/2017       12/31/2017  1

Вы можете определить, является ли период непосредственно последовательным, проверяя, равняется ли period_end в предыдущей строке значение period_start текущей строки (это верно для всего набора данных, чтобы идентифицировать непосредственно последовательные периоды).

I думаю, здесь есть решение, включающее GROUP BY, но я его не вижу. Любая помощь будет отличной. Спасибо!

Ответы [ 2 ]

1 голос
/ 24 января 2020
with a as (
    select *,
        case when lag(period_end) over (partition by event_id, rating order by period_start) = period_start
           then 0 else 1 end as brk
    from T
) b as (
    select *,
        sum(brk) over (partition by event_id, rating order by period_start) as grp
    from a
)
select event_id, min(period_start) as period_start, max(period_end) as period_end, rating
from b
group by event_id, grp, rating
order by event_id, grp, rating

Определите, какие строки являются разрывами в серии, пометив их как 1. Пронумеруйте группы путем подсчета разрывов, промежуточного итога. Используйте group by, чтобы свернуть в один ряд.

0 голосов
/ 24 января 2020

Это проблема пробелов и островков. Основная идея состоит в том, чтобы использовать lag(), чтобы найти, где значение изменяется, а затем сделать кумулятивную сумму для назначения групп.

Однако я предпочел отставание в столбце date вместо столбца значение . Оказывается, это гораздо удобнее, когда у вас есть несколько значений, которые могут измениться.

В вашем случае это выглядит так:

select event_id, min(period_start), max(period_end), rating
from (select t.*,
             sum(case when prev_period_end = period_end then 0 else 1 end) over (partition by event_id order by period_start) as grp
      from (select t.*,
                   lag(period_end) over (partition by event_id, rating order by period_start) as prev_period_end
            from t
           ) t
     ) t
group by event_id, rating, grp;
...