Che*_*izz 7 postgresql json postgresql-9.5
我有一张看起来像这样的桌子
id | json_column
---+------------
1 | {"text1":"a", "text2":"b", "text3":"c", ....}
2 | {"text1":"b", "text2":"c", ....}
Run Code Online (Sandbox Code Playgroud)
我希望它像这样
text1 | text2 | text3 | ....
a | b | c | ....
b | c | d | ....
Run Code Online (Sandbox Code Playgroud)
我发现得到这个结果的一个变体是使用 json_populate_record() 并创建一个新类型 x as (text1 text, text2 text, text3 text,....) 所以我可以执行
select (json_populate_record(null::x, json_column)).* from table
Run Code Online (Sandbox Code Playgroud)
有没有另一种方法可以在不创建上述类型的情况下做到这一点?所有新列都可以有类型文本,那么可能有快捷方式吗?
我的问题是我在 aaaa_bbbb_cccc_d 形式的一个 json 字段中有 50 个键,因此手动为此创建一种类型会花费很多时间
我正在使用 9.5.4
没有办法让您免于在选择列表中指定所有 JSON 属性,无论是通过“虚拟类型”隐式还是显式,例如使用以下内容:
select json_column ->> 'text1' as text1,
json_column ->> 'text2' as text2,
...
from the_table;
Run Code Online (Sandbox Code Playgroud)
您可以做的是通过基于 JSON 文档中的不同属性自动创建具有所有属性的视图来简化此操作。
以下代码将使用 JSON 列中的所有不同键重新创建视图:
do
$$
declare
l_keys text;
begin
drop view if exists v_json_view cascade;
select string_agg(distinct format('json_column ->> %L as %I',jkey, jkey), ', ')
into l_keys
from the_table, json_object_keys(json_column) as t(jkey);
execute 'create view v_json_view as select '||l_keys||' from the_table';
end;
$$
;
Run Code Online (Sandbox Code Playgroud)
每次所有 json 文档中的键列表发生更改时,您都需要运行上述命令。从理论上讲,这可以在触发器中完成,但如果您在该表上运行许多更新,这可能不是一个好主意。
如果 JSON 键的总数有点“稳定”,您可以安排一个 cron 作业定期重新创建该视图。
您还受到表或视图中最大列数的限制。如果您有比大约更多的(不同的)键。1600(可能更少)以上将失败。