我在jsonb数组上进行横向交叉连接,我希望得到数组元素的row_number(或它的等价物)。看看row_number文档我发现我需要做一个"命令"除了""之外的分区,但我并没有真正的排序标准 - 数组只有一个设定顺序,我需要将索引检索到数组中其余的数据。
客户端表格将包含这样的条目
{
"id": "cj49q33oa000",
"email": {
"address": "",
"after": "2016-06-28T12:28:58.016Z",
"error": "Et corporis sed."
},
"name": "Arnold Schinner",
"birthdate": "2016-07-29T05:09:33.693Z",
"status": "paused",
"sex": "f",
"waist": [
{
"completed": "2017-06-23T10:37:37.500Z"
},
{
"planned": "2017-06-23T10:37:37.500Z"
},
{
"planned": "2017-06-23T10:37:37.500Z"
},
{
"planned": "2017-06-23T10:37:37.500Z"
}
]
}
我会运行像
这样的查询SELECT client->>'id' AS id, waist.planned
FROM clients
CROSS JOIN LATERAL JSONB_TO_RECORDSET(client->'waist') AS waist(planned TIMESTAMP WITH TIME ZONE)
WHERE waist.planned IS NOT NULL
但我需要以某种方式获得waist.position_in_array
。
答案 0 :(得分:1)
使用功能jsonb_array_elements(...)
with ordinality.
SELECT client->>'id' AS id, (value->>'planned')::timestamptz as planned, ordinality
FROM clients
CROSS JOIN LATERAL jsonb_array_elements(client->'waist') with ordinality
WHERE value->>'planned' IS NOT NULL;
id | planned | ordinality
--------------+--------------------------+------------
cj49q33oa000 | 2017-06-23 12:37:37.5+02 | 1
cj49q33oa000 | 2017-06-23 12:37:37.5+02 | 2
cj49q33oa000 | 2017-06-23 12:37:37.5+02 | 3
cj49q33oa000 | 2017-06-23 12:37:37.5+02 | 4
(4 rows)
答案 1 :(得分:0)
您可以使用ROWS FROM语法将json_to_recordset
和jsonb_to_recordset
与WITH ORDINALITY
组合在一起。
9.5年代的文档说
ROWS FROM(function_call [,...])[有序性] [[AS] table_alias [(column_alias [,...])]]
所以这可行(已在12上测试,但至少应在所有> = 9.5的版本上可行)
WITH my_json AS (
SELECT '[{"id":1, "name":"somename", "bool":true},{"id":2, "name":null, "bool":false}]'::json jsn
)
SELECT jsn_with_ordinality.*
FROM my_json,
ROWS FROM (json_to_recordset(jsn) AS (id int, name TEXT, bool boolean)) WITH ORDINALITY jsn_with_ordinality;
结果:
id|name |bool |ordinality|
--|--------|-----|----------|
1|somename|true | 1|
2| |false| 2|
但是,我确实想知道是否比添加row_number() over()...