Postgres:使用索引将JSON数组元素扩展为值?

时间:2018-02-16 09:43:57

标签: json postgresql

我有一个包含JSON数组的列的表。举个例子:

with example as (
    select '["a", "b"]'::jsonb as col
    union select ('["c", "d", "e"]'::jsonb) as col
)
select col from example

返回:

col
["a", "b"]
["c", "d", "e"]

我可以使用jsonb_array_elements将每个数组扩展为行:

select jsonb_array_elements(col) from example

返回:

jsonb_array_elements
"a"
"b"
"c"
"d"
"e"

我想要每个数组元素的索引以及元素本身(有点像Python的enumerate),如下所示:

jsonb_array_elements    array_index
"a"                     1
"b"                     2
"c"                     1
"d"                     2
"e"                     3

我该怎么做?

我的应用程序具有只读访问权限,因此无法创建函数。

2 个答案:

答案 0 :(得分:2)

使用with ordinality

with example (col) as (
  values 
    ('["a", "b"]'::jsonb),  
    ('["c", "d", "e"]'::jsonb)
)
select t.*
from example, jsonb_array_elements(col) with ordinality as t(e,idx)

返回:

e   | idx
----+----
"a" |   1
"b" |   2
"c" |   1
"d" |   2
"e" |   3
只有在with ordinality子句中使用set returns函数时才能使用

from,这是强烈建议的。

答案 1 :(得分:1)

啊,这是一个有趣的小postgres拼图。下面怎么样?

   WITH example1 AS (
        SELECT '["a", "b"]'::jsonb AS col

    ),
    example2 AS (
        SELECT ('["c", "d", "e"]'::jsonb) AS col
    )

    SELECT  1 AS group, jsonb_array_elements(col) AS jcol, row_number() OVER (ORDER BY jsonb_array_elements(col)) FROM example1
    UNION
    SELECT 2 AS group, jsonb_array_elements(col) AS jcol, row_number() OVER (ORDER BY jsonb_array_elements(col)) FROM example2
    ORDER BY "group", row_number ASC;

那会给你

1   "a" 1
1   "b" 2
2   "c" 1
2   "d" 2
2   "e" 3