SQL Создать столбец с group_id в операторе SELECT - PullRequest
0 голосов
/ 24 января 2019

Я пытаюсь создать столбец с group_id во время оператора SELECT.

В качестве группы мы будем принимать каждую комбинацию contact_id и product_code, пока не найдем событие = покупка.Тогда, если есть другое событие с той же комбинацией contact_id и product_code, оно будет назначено как другая группа.Также комбинация contact_id и product_code без события = покупка будет независимой группой.

Существует более одной комбинации contact_id-product_code, и данные не отсортированы в таблице.

Ниже таблицы иожидаемый результат после SELECT

contact_id | product_code | timestamp               | event      |
------------------------------------------------------------------
contact_1  | product_1    | 2018-11-29 11:11:00.000 |   view     |
contact_1  | product_1    | 2018-11-29 13:10:00.000 |   add      |
contact_1  | product_1    | 2018-11-30 10:20:00.000 |   purchase |
contact_1  | product_1    | 2018-12-03 10:20:00.000 |   mail     |
contact_1  | product_1    | 2018-12-03 16:00:00.000 |   purchase |
contact_2  | product_2    | 2018-12-05 19:01:00.000 |   add      |
contact_2  | product_2    | 2018-12-05 19:03:00.000 |   purchase |
contact_3  | product_3    | 2018-12-05 19:03:00.000 |   view     |
contact_4  | product_4    | 2018-11-15 19:03:00.000 |   mail     |
contact_4  | product_4    | 2018-11-15 19:03:00.000 |   purchase |
contact_5  | product_5    | 2018-11-20 19:03:00.000 |   purchase |

Результат:

contact_id | product_code | timestamp               | event      | id_groups|
-----------------------------------------------------------------------------
contact_1  | product_1    | 2018-11-29 11:11:00.000 |   view     |    1     |
contact_1  | product_1    | 2018-11-29 13:10:00.000 |   add      |    1     |
contact_1  | product_1    | 2018-11-30 10:20:00.000 |   purchase |    1     |
contact_1  | product_1    | 2018-12-03 10:20:00.000 |   mail     |    2     |
contact_1  | product_1    | 2018-12-03 16:00:00.000 |   purchase |    2     |
contact_2  | product_2    | 2018-12-05 19:01:00.000 |   add      |    3     |
contact_2  | product_2    | 2018-12-05 19:03:00.000 |   purchase |    3     |
contact_3  | product_3    | 2018-12-05 19:03:00.000 |   view     |    4     |
contact_4  | product_4    | 2018-11-15 19:03:00.000 |   mail     |    5     |
contact_4  | product_4    | 2018-11-15 19:03:00.000 |   purchase |    5     |
contact_5  | product_5    | 2018-11-20 19:03:00.000 |   purchase |    6     |

Ответы [ 2 ]

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

Иметь коррелированный подзапрос, который подсчитывает количество строк покупки с более ранней отметкой времени, и добавляет 1.

select t1.*,
      (select count(*) + 1 from tablename t2
       where t2.event = 'purchase' and t2.timestamp < t1.timestamp) as id_groups
from tablename t1

Core ANSI SQL-совместимый.

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

Вы можете сделать это с накопленной суммой.Только для задания:

select t.*,
       coalesce(sum(case when event = 'purchase' then 1 else 0 end) over
                    (order by contact_id, product_code, timestamp desc
                     rows between unbounded preceding and 1 preceding
                    ), 1) as grp
from t;

Здесь - это дБ <> скрипка.

РЕДАКТИРОВАТЬ:

Я признаю, что просто не понимаю, почемулогика полезна, потому что группы назначаются сначала по продукту, а затем по времени.Очень странно.

Группы назначаются следующим образом:

select t.*,
       sum(case when prev_event = 'purchase' or seqnum = 1 then 1 else 0 end) over
                (order by contact_id, product_code, timestamp) as grp
from (select t.*,
             row_number() over (partition by contact_id, product_code order by timestamp) as seqnum,
             lag(event) over (order by contact_id, product_code, timestamp) as prev_event
      from t
     ) t
order by 1, 2, 3;

Вы можете использовать dense_rank() для назначения нужных последовательных номеров:

select t.*, dense_rank() over (order by _grp) as grp
from (select t.*,
             sum(case when prev_event = 'purchase' or seqnum = 1 then 1 else 0 end) over
                      (order by contact_id, product_code, timestamp) as _grp
      from (select t.*,
                   row_number() over (partition by contact_id, product_code order by timestamp) as seqnum,
                   lag(event) over (order by contact_id, product_code, timestamp) as prev_event
            from t
           ) t
     ) t
order by 1, 2, 3;

Здесь - это дБ <> скрипка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...