SQL: группировка записей для пути

Мой SQL немного ржавый, поэтому вопрос, но это также означает, что я немного не уверен, как точно сформулировать вопрос. Я надеюсь, что пример ниже объясняет это лучше.

У меня есть список записей, по идентификатору пользователя:

ID | Channel  | FiscalPeriod | Amount
======================================
A  | Online   | 201710       | 20.00
A  | Online   | 201709       | 20.00
A  | Voucher  | 201708       | 20.00
A  | Voucher  | 201707       | 20.00
A  | Voucher  | 201706       | 20.00
A  | Online   | 201705       | 20.00
A  | Online   | 201704       | 20.00

Мне нужно сгруппировать поле "канал", но не как полную группу, так как упорядочение по финансовому периоду важно, поэтому набор результатов будет выглядеть следующим образом:

ID | Channel  | MAX(FiscalPeriod) | Amount
==========================================
A  | Online   | 201710            | 40.00
A  | Voucher  | 201708            | 60.00
A  | Online   | 201705            | 40.00

Для отслеживания выходных данных приведенный выше порядок действительно важен, поэтому я вижу, что онлайн << ваучер << онлайн был путем пользователя

2 ответа

Я бы подошел к этому, используя подход с разницей номеров строк с агрегацией:

select id, channel
       max(fiscalperiod) as max_fiscalperiod
       sum(amount) as amount
from (select t.*,
             row_number() over (partition by id order by fiscalperiod) as seqnum_i,
             row_number() over (partition by id, channel order by fiscalperiod) seqnum_ic
      from t
     ) t
group by id, channel, (seqnum_i - seqnum_ic);

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

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

select distinct id,channel
,max(fiscalperiod) over(partition by id,channel,grp) as max_fiscalperiod
,sum(amount) over(partition by id,channel,grp) as amount
from (select t.*,
      row_number() over(partition by id order by fiscalperiod)
      -row_number() over(partition by id,channel order by fiscalperiod) as grp
      from tbl t
     ) t
Другие вопросы по тегам