我的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
类型
答案 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数组连接起来。