Cyb*_*lle 5 postgresql select json
我有一个类型为字段的表jsonb,我想为所有 json 键拆分字段 jsonb 的列。此列缺少架构。例如:
从
CREATE TABLE v(id,jsonb)
AS VALUES
(1,'{"a":"4", "b":"5"}'::jsonb),
(2,'{}'),
(3,'{"a":"8", "c":"9", "d":"9"}');
Run Code Online (Sandbox Code Playgroud)
到
id | a | b | c | d
1 | 4 | 5 | |
3 | 8 | | 9 | 9
Run Code Online (Sandbox Code Playgroud)
对于这种特定情况,一种解决方案是
select * from table, json_to_record(optional) as x("a" text, "b" text, "c" text, d text)
Run Code Online (Sandbox Code Playgroud)
如您所见,键可能会有所不同,并且在大型数据库中很难将所有键都放在我的实际问题中,我有 31 个键,另一方面,如果我想在其他表中重用此脚本,我必须手动填充键。
有没有办法在 jsonb 的所有键上进行选择而无需手动指定键?
我的问题:有没有办法在 jsonb 的所有键上进行选择,而无需手动指定键?
不可以,因为没有办法让查询返回未定义的结果集。但是,如果表不接受新查询,您可以生成动态 sql 语句。
SELECT FORMAT(
$$ SELECT * FROM %I.%I CROSS JOIN LATERAL jsonb_to_record(%I) AS rs(%s); $$,
'public',
'v',
'jsonb',
array_to_string(
(SELECT ARRAY(SELECT DISTINCT col FROM v CROSS JOIN LATERAL jsonb_object_keys(jsonb) AS t(col) ORDER BY col)), ' text , '
) || ' text'
);
Run Code Online (Sandbox Code Playgroud)
然后运行该查询,或\gexec在 psql 中运行。
format
--------------------------------------------------------------------------------------------------------------
SELECT * FROM public.v CROSS JOIN LATERAL jsonb_to_record(jsonb) AS rs(a text , b text , c text , d text);
(1 row)
test=# \gexec
id | jsonb | a | b | c | d
----+--------------------------------+---+---+---+---
1 | {"a": "4", "b": "5"} | 4 | 5 | |
2 | {} | | | |
3 | {"a": "8", "c": "9", "d": "9"} | 8 | | 9 | 9
(3 rows)
Run Code Online (Sandbox Code Playgroud)
您可能想也可能不想构建一些jsonb_typeof返回 pg 类型的类型推断:请记住,您永远不能返回整数或其他东西,但您应该能够将数字存储为double precision.
| 归档时间: |
|
| 查看次数: |
2777 次 |
| 最近记录: |