如果您知道您的user_action列中没有很多操作,您可以使用递归子查询和union all来避免使用辅助表numbers。但是,这需要您知道每个用户的操作数量,要么调整初始表格,要么为其创建视图或临时表格。
数据准备
假设您有以下表格:
create temporary table actions
(
user_id varchar,
user_name varchar,
user_action varchar
);
我会在其中插入一些值:
insert into actions
values (1, 'Shone', 'start,stop,cancel'),
(2, 'Gregory', 'find,diagnose,taunt'),
(3, 'Robot', 'kill,destroy');
这是一个带有临时计数的附加表格
,其中包含HTML代码。
create temporary table actions_with_counts
(
id varchar,
name varchar,
num_actions integer,
actions varchar
);
insert into actions_with_counts (
select user_id,
user_name,
regexp_count(user_action, ',') + 1 as num_actions,
user_action
from actions
);
这将是我们的“输入表”,它看起来正如您所期望的那样。
select * from actions_with_counts;
ID |
名称 |
操作数 |
操作 |
2 |
格雷戈里 |
3 |
查找、诊断、嘲讽 |
3 |
机器人 |
2 |
杀死、摧毁 |
1 |
肖恩 |
3 |
启动、停止、取消 |
再次提醒,您可以调整初始表格,因此跳过将计数作为单独表格添加。
子查询以展开操作
Here's the unnesting query:
with recursive tmp (user_id, user_name, idx, user_action) as
(
select id,
name,
1 as idx,
split_part(actions, ',', 1) as user_action
from actions_with_counts
union all
select user_id,
user_name,
idx + 1 as idx,
split_part(actions, ',', idx + 1)
from actions_with_counts
join tmp on actions_with_counts.id = tmp.user_id
where idx < num_actions
)
select user_id, user_name, user_action as parsed_action
from tmp
order by user_id;
这将为每个操作创建一行,输出将如下所示:
用户ID |
用户名 |
已解析动作 |
1 |
Shone |
开始 |
1 |
Shone |
停止 |
1 |
Shone |
取消 |
2 |
Gregory |
查找 |
2 |
Gregory |
诊断 |
2 |
Gregory |
嘲讽 |
3 |
机器人 |
杀死 |
3 |
机器人 |
摧毁 |