从 jsonb_array_elements 或 jsonb_to_recordset 获取 row_number

ret*_*ere 5 postgresql json jsonb

我正在 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"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我会运行一个查询

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
Run Code Online (Sandbox Code Playgroud)

但我需要以waist.position_in_array某种方式进入。

kli*_*lin 7

使用功能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 |          2
 cj49q33oa000 | 2017-06-23 12:37:37.5+02 |          3
 cj49q33oa000 | 2017-06-23 12:37:37.5+02 |          4
(4 rows)
Run Code Online (Sandbox Code Playgroud)

Db<>小提琴。