雪花展平方案

Snowflake Flatten scenario

我在源 table 中有一些变体结构,我需要阅读、查找并将另一个变体结构进入目标 table。

-- 来源 table:点击次数

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'
);

-- 目标 table: clicks_processed

create table clicks_processed
(payload variant,
 click_events variant )

查找table: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 table.

clicks_processed table 的有效载荷列与点击 table 的相同有效载荷。

click_events 列 clicks_processed table:event_ids 键必须从 clicks.payload 中拉出并与查找 table "click_event" 形成将插入到 clicks_processed

的 click_event 列的变体

期望的输出:clicks_processed(只有来自 click_event 的匹配 event_id 会在 click_events 下填充)

注意:第一个记录的 click_event 为空,因为 event_ids 的 none 来自 click_event 查找 table(仍然需要记录)

我目前想出的代码:

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

如果所有记录都匹配 click_event 的 event_ids 则工作正常,否则不匹配(上面示例中的第一条记录),与 click_event 的左连接也没有'帮不上忙。

另外,不确定这是否是最好的代码,特别担心 max(payload) 和 group by 的使用。在实际场景中,有效载荷很大,大约有 500 个键,event_ids 可以容纳大约 30-50 个事件,这意味着展平也会破坏尽可能多的记录。

谢谢!

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。

此外,在 max() 函数上利用 any_value() 函数,因为该值在 seq 值中始终相同。