Postgresql json列查看

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

a_h*_*ame 6

没有办法让您免于在选择列表中指定所有 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(可能更少)以上失败。