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

时间:2016-03-23 09:57:15

标签: arrays json postgresql

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

Serveur.prototype.demandConnexion = function(idZEP) {

     if (this.ZP.createZE(idZEP))

         {

         console.log(' ==> socket : demande de creation ZE pour '+idZEP +' accepte');

         }

     else

         {

         console.log(' ==> socket : demande de creation ZE pour '+idZEP +' refuse');

         }
};

Serveur.prototype.traitementSurConnection = function(socket) {

    // console.log('connexion');

    console.log(' ==> socket connexion');

    // traitement de l'evenement DEMANDE DE CONNEXION D'UNE ZE

    socket.on('connection', (function(idZEP) { this.demandConnexion(idZEP)

        console.log('good')

}))

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

    [
        {
            "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"
        }
    ]

我尝试使用 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 类型

3 个答案:

答案 0 :(得分:33)

我在评论部分发布了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] |
 -------------

Here可以找到v9.4的文档。

答案 1 :(得分:21)

我建议在你的情况下使用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键)可以自由进一步扩展。

答案 2 :(得分:13)

更难的例子:

假设您有一个包含每行包含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)lateral join的缩写形式,它有效地将categories中的每一行与jsonb_to_recordset函数创建的虚拟表从同一行中的jsonb数组连接起来。