Сценарий "Снежинка" - PullRequest
0 голосов
/ 29 мая 2020

У меня есть некая структура вариантов в исходной таблице, которую мне нужно прочитать, найти и перейти в другую структуру вариантов в целевую таблицу.

- Исходная таблица: клики

create table clicks
(payload variant
);

- установить данные в кликах

insert into clicks
select 
object_construct(
  'language', 'en-us',
  'browser', 'chrome',  
  'color', '35',
  'event_ids', '190,195'
)
union
object_construct(
  'language', 'en-us',
  'browser', 'chrome',  
  'color', '32',
  'event_ids', '201,203,190,195'
)
union
select 
object_construct(
  'language', 'en-us',
  'browser', 'mozilla',  
  'color', '38',
  'event_ids', '188,190,202,203,195,176'
);

- Целевая таблица: clicks_processed

create table clicks_processed
(payload variant,
 click_events variant )

Таблица поиска: click_event

create table click_event
(
  key varchar,
  event_id varchar,
  desc varchar  
)

- настроить данные для click_event

insert into click_event (key,event_id,desc)
select 'event201','201','pic_click'
union
select 'event202','202','vid_view'
union
select 'event203','203','download'

Требование: вставить записи в таблицу clicks_processed.

Столбец полезной нагрузки таблицы clicks_processed та же полезная нагрузка из таблицы кликов.

Столбец click_events таблицы clicks_processed: ключ event_ids должен быть извлечен из clicks.payload и объединен с таблицей поиска «click_event», чтобы сформировать вариант, который будет вставлен в столбец click_events of clicks_processed

Желаемый результат: clicks_processed (только совпадающий event_id из click_event заполняется в click_events)

data of clicks_processed

Примечание: первая запись имеет null для click_events, потому что ни один из идентификаторов event_ids не соответствует таблице поиска click_event (по-прежнему нужна запись)

Текущий код, который я придумал:

select max(payload),
object_agg(e.key,object_construct(
'code', e.event_id,
'desc', e.desc
)) as click_events
from clicks c, table(flatten(input => split(c.payload:event_ids,','))) as f
inner join click_event e on e.event_id = f.value
group by seq

Это нормально работает, если все записи имеют совпадающие идентификаторы event_id с идентификатором click_event, иначе нет (первая запись в примере выше), левое соединение с click_event также не помогло.

Кроме того, не уверен, что это - лучший фрагмент кода, особенно беспокоит использование max (полезной нагрузки) и group by. В реальном сценарии полезная нагрузка огромна, около 500 ключей, а event_ids может содержать около 30-50 событий, что означает, что сглаживание также взрывает столько же записей.

Спасибо!

1 Ответ

0 голосов
/ 29 мая 2020
select any_value(payload),
       object_agg(e.key,object_construct(
            'code', e.event_id,
            'desc', e.desc
            )) as click_events
from (
  select f.seq, f.value::varchar as value, c.payload
  from clicks c, 
  lateral flatten(input => split(c.payload:event_ids,',')) as f
  ) a
left join click_event e
  on a.value = e.event_id
group by a.seq;

Сгладьте массив, а затем снова присоединитесь к click_event как левое соединение. Тем не менее, это дает вам пустой массив, а не NULL. 1007 *

...