繁体   English   中英

如何将json数组转换为postgres中的行

[英]How to turn a json array into rows in postgres

我的 postgres 数据库中存储了一个 json 数组。 json 看起来像这样:

    [
        {
            "operation": "U",
            "taxCode": "1000",
            "description": "iva description",
            "tax": "12"
        },
        {
            "operation": "U",
            "taxCode": "1001",
            "description": "iva description",
            "tax": "12"
        },
        {
            "operation": "U",
            "taxCode": "1002",
            "description": "iva description",
            "tax": "12"
        }
    ]

现在我需要选择数组,以便任何元素都在查询结果的不同行中。 所以我执行的SELECT语句必须以这种方式返回数据:

 data
--------------------------------------------------------------------------------------
 { "operation": "U", "taxCode": "1000", "description": "iva description", "tax":"12"}
 { "operation": "U", "taxCode": "1001", "description": "iva description", "tax":"12"}
 { "operation": "U", "taxCode": "1002", "description": "iva description", "tax":"12"}

我尝试使用unnest()函数

SELECT unnest(json_data::json)
FROM my_table

但它不接受jsonb类型

我在评论部分发布了最初由 pozs 撰写的答案。

unnest()用于 PostgreSQL 的数组类型。

可以使用以下功能之一:

  • json_array_elements(json) (9.3+)
  • jsonb_array_elements(jsonb) (9.4+)
  • json[b]_array_elements_text(json[b]) (9.4+)

示例

select * from json_array_elements('[1,true, [2,false]]')

产值

 -------------
 | 1         |
 -------------
 | true      |
 -------------
 | [2,false] |
 -------------

这里可以找到 v9.4 的文档。

更难的例子:

假设您有一个表,每行都包含 jsonb 数组,并且您希望将所有这些数组拆分(或取消嵌套)并对其中包含的记录进行一些聚合计算。

表(让它成为categories ):

 id | specifics (jsonb)
-----------------------------------------------------------------------------------
  1 | [{"name": "Brand", "required": true}, {"name": "Color", "required": false}]
  2 | [{"name": "Brand", "required": false}, {"name": "Color", "required": false}]

所以,如果你想计算你有多少所需的细节,你需要使用这样的查询:

SELECT specs.name, COUNT(*) AS total
FROM 
  categories, 
  jsonb_to_recordset(categories.specifics) AS specs(name jsonb, required boolean)
WHERE 
  specs.required = TRUE
  -- AND any other restrictions you need
GROUP BY specs.name
ORDER BY total DESC;

这里FROM x, function(x.column)横向连接的缩写形式,它有效地将categories每一行与同一行中的 jsonb 数组中的jsonb_to_recordset函数创建的虚拟表连接起来。

结果将是:

 name  | total
---------------
 Brand |     1

链接到 DB Fiddle: https : //www.db-fiddle.com/f/c4xZcEgg9dsPVDtE7Keovv/0

我建议在您的情况下使用 json_to_recordset 命令。 你的 SQL 应该是:

select *
from json_to_recordset('[{"operation":"U","taxCode":1000},{"operation":"U","taxCode":10001}]')
as x("operation" text, "taxCode" int);

输出是:

------------------------
|   |operation|taxCode |
------------------------
| 1 |   "U"   |   1000 |
------------------------
| 2 |   "U"   |  10001 |
------------------------

示例的列(或 JSON 键)可以进一步自由扩展。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM