Json 对象数组 PostgreSQL Table 格式

Json Arrays of objects PostgreSQL Table format

我有一个 JSON 文件(对象数组),我必须使用 PostgreSQL 查询将其转换为 table 格式。

遵循示例数据。 "b"、"c"、"d"、"e" 将作为单独的 table 提取,因为它们是数组,并且在这些数组中,有对象

我试过使用 json_populate_recordset(),但它只有在我只有一个数组时才有效。

[{a:"1",b:"2"},{a:"10",b:"20"}]

我参考了一些链接和代码。

jsonb_array_element example

postgreSQL functions

Expected Output

Sample Data: 

    { 
       "b":[ 
           {columnB1:value, columnB2:value},
           {columnB1:value, columnB2:value},
        ],
       "c":[
           {columnC1:value, columnC2:value, columnC3:value},
           {columnC1:value, columnC2:value, columnC3:value},
           {columnC1:value, columnC2:value, columnC3:value}
        ],
        "d":[
           {columnD1:value, columnD2:value},
           {columnD1:value, columnD2:value},
        ],
       "e":[
           {columnE1:value, columnE2:value},
          
        ]
    }
       

预期输出

b 应该是一个 table,其中显示了 columnA1 和 columnA2 及其值。 同样 table c、d、e 及其各自的列和值。

Expected Output

您可以使用 jsonb_to_recordset(),但您需要取消嵌套 JSON。您需要内联执行此操作,因为这是一个不能使用派生值的 JSON Processing Function

我使用经过验证的 JSON 作为此答案末尾的简化和格式

要解除 JSON 的嵌套,请使用下面的符号 extracts JSON object field 和给定的键。

--one level
select '{"a":1}'::json->'a' 
result : 1
--two levels
select '{"a":{"b":[2]}}'::json->'a'->'b'
result : [2]

我们现在将其扩展为包括 json_to_recordset()

select * from 
json_to_recordset(
  '{"a":{"b":[{"f1":2,"f2":4},{"f1":3,"f2":6}]}}'::json->'a'->'b' --inner table b 
) 
as x("f1" int, "f2" int); --fields from table b

或使用json_array_elements。无论哪种方式,我们都需要列出我们的字段。第二种解决方案类型将是 json 而不是 int 所以你不能求和 etc

with b as (select json_array_elements('{"a":{"b":[{"f1":2,"f2":4},{"f1":3,"f2":6}]}}'::json->'a'->'b') as jx)
select jx->'f1' as f1, jx->'f2' as f2 from b;

输出

f1  f2
2   4
3   6

我们现在在 jsonb_to_recordset()

中使用您的数据结构
select * from jsonb_to_recordset( '{"a":{"b":[{"columnname1b":"value1b","columnname2b":"value2b"},{"columnname1b":"value","columnname2b":"value"}],"c":[{"columnname1":"value","columnname2":"value"},{"columnname1":"value","columnname2":"value"},{"columnname1":"value","columnname2":"value"}]}}'::jsonb->'a'->'b') as x(columnname1b text, columnname2b text);

输出:

columnname1b    columnname2b
value1b         value2b
value           value

对于tablec

select * from jsonb_to_recordset( '{"a":{"b":[{"columnname1b":"value1b","columnname2b":"value2b"},{"columnname1b":"value","columnname2b":"value"}],"c":[{"columnname1":"value","columnname2":"value"},{"columnname1":"value","columnname2":"value"},{"columnname1":"value","columnname2":"value"}]}}'::jsonb->'a'->'c') as x(columnname1 text, columnname2 text);

输出

columnname1 columnname2
value   value
value   value
value   value

样本JSON

{
  "a": {
    "b": [
      {
        "columnname1b": "value1b",
        "columnname2b": "value2b"
      },
      {
        "columnname1b": "value",
        "columnname2b": "value"
      }
    ],
    "c": [
      {
        "columnname1": "value",
        "columnname2": "value"
      },
      {
        "columnname1": "value",
        "columnname2": "value"
      },
      {
        "columnname1": "value",
        "columnname2": "value"
      }
    ]
  }
}

好吧,我想到了一些想法,这是一个行之有效的想法。我一次可以得到一个 table。 https://www.postgresql.org/docs/9.5/functions-json.html

我正在使用 json_populate_recordset。

第一个 select 语句中使用的列来自 table,其列是我们试图提取到 table 的 JSON 类型。

json_populate_recordset 函数中的 'tablename from column' 是我们试图提取的 table,后面跟着它的列和数据类型。

WITH input AS(
   SELECT cast(column as json) as a
   FROM tablename
)
SELECT b.*
FROM input c,
            json_populate_recordset(NULL::record,c.a->'tablename from column') as b(columnname1 datatype, columnname2 datatype)