sql - 将一列拆分为多列(数量和名称未知)
问题描述
考虑我有一个这样的表:
示例
ID Name Something Params
-----------------------------------------
1 First A241FRT P1=12, P2=One
2 Second G924PEM P1=19
3 Third L9449TY P1=94, P2=Two
我需要将列拆分Params
为多个。所以我需要得到这样的东西:
预期结果
ID Name Something P1 P2
-----------------------------------------
1 First A241FRT 12 One
2 Second G924PEM 19
3 Third L9449TY 94 Two
我不知道额外列的名称以及数量。
我不是很擅长 SQL,所以我非常需要你的帮助,谢谢大家
解决方案
我会将参数转换为 json 值,然后提取键:
select id, name, something,
params ->> 'P1' as p1,
params ->> 'P2' as p2
from (
select id,
name,
something,
concat('{',
regexp_replace(regexp_replace(params, '(P[0-9])=', '"\1":', 'gi'),
':(\w+)', ':"\1"', 'gi'),
'}')::jsonb
from the_table
) t
如果您经常需要,创建一个将“参数”转换为 JSON 表示的函数可能是有意义的:
create function params_to_json(p_params text)
returns jsonb
as
$$
select jsonb_object_agg(split_part(p, '=', 1), split_part(p, '=', 2))
from regexp_split_to_table(p_params, ',\s*') as t(p)
$$
language sql
stable
;
然后你可以像这样使用它:
select id, name, something,
params_to_json(params) ->> 'P1' as p1,
params_to_json(params) ->> 'P2' as p2
from data
该函数对于未知键更加灵活,因为它只假设键/值对由 a 分隔,,
并且键和值由 a 分隔=
推荐阅读
- postgresql - PostgreSQL - 如何在标记为 FOR EACH STATEMENT 的触发过程中获取新记录?
- javascript - 如何在下拉图标下方放置菜单列表?
- apache-camel - 为什么 MultipartEntityBuilder 会抛出 org.apache.http.ContentTooLongException?
- android - 使用首选项时整数不能转换为布尔值
- ios - 如何在 iOS Swift 中获取实际的日期和时间?即使用户从设备设置中更改了日期和时间
- php - 有没有更快的方法来查找 PHP 中两个数组之间的匹配项?
- c# - 重载具有相同数量的参数和相同类型的方法
- node.js - 获取 mongodb 集合列表和文档数
- c# - 在输入字段中粘贴问题-Unity
- javascript - 提交后以 Angular 5 重置表单