Arrays 使用PostgreSQL从JSON提取到多列

Arrays 使用PostgreSQL从JSON提取到多列,arrays,json,postgresql,select,postgresql-9.6,Arrays,Json,Postgresql,Select,Postgresql 9.6,我有一个列item_id,其中包含JSON(like?)结构中的数据 +----------+---------------------------------------------------------------------------------------------------------------------------------------+ | id |

我有一个列
item_id
,其中包含JSON(like?)结构中的数据

+----------+---------------------------------------------------------------------------------------------------------------------------------------+
|     id   |                                                                item_id                                                                |
+----------+---------------------------------------------------------------------------------------------------------------------------------------+
|    56711 | {itemID":["0530#2#1974","0538\/2#2#1974","0538\/3#2#1974","0538\/18#2#1974","0539#2#1974"]}"                                          |
|    56712 | {itemID":["0138528#2#4221","0138529#2#4221","0138530#2#4221","0138539#2#4221","0118623\/2#2#4220"]}"                                  |
|    56721 | {itemID":["2704\/1#1#1356"]}"                                                                                                         |
|    56722 | {itemID":["0825\/2#2#3349","0840#2#3349","0844\/10#2#3349","0844\/11#2#3349","0844\/13#2#3349","0844\/14#2#3349","0844\/15#2#3349"]}" |
|    57638 | {itemID":["0161\/1#2#3364","0162\/1#2#3364","0163\/2#2#3364"]}"                                                                       |
|    57638 | {itemID":["109#1#3364","110\/1#1#3364"]}"                                                                                             |
+----------+---------------------------------------------------------------------------------------------------------------------------------------+
我需要每个逗号前的最后四位数字(如果有),最后四位数字要区分并分隔成单独的列。
distinct也应该在
id
之间发生,因此只允许一个id为57638的结果行

下面是一个代码草案,它没有给出正确的答案。 预期结果应如下所示:

+----------+-----------+-----------+
|    id    | item_id_1 | item_id_2 |
+----------+-----------+-----------+
|    56711 |      1974 |           |
|    56712 |      4220 |      4221 |
|    56721 |      1356 |           |
|    56722 |      3349 |           |
|    57638 |      3364 |      3365 |
+----------+-----------+-----------+

结果中可能有很多“item\u id\u%”列。

您可以取消json数组的测试,将每个元素的最后4个字符作为一个数字,然后进行条件聚合:

select 
    id,
    max(val) filter(where rn = 1) item_id_1,
    max(val) filter(where rn = 2) item_id_2
from (
    select
        id,
        right(val, 4)::int val,
        dense_rank() over(partition by id order by right(val, 4)::int) rn
    from mytable t
    cross join lateral jsonb_array_elements_text(t.item_id -> 'itemID') as x(val)
) t
group by id
您可以向外部查询添加更多的条件
max()
s,以处理更多可能的值

id | item_id_1 | item_id_1 ----: | --------: | --------: 56711 | 1974 | null 56712 | 4220 | 4221 56721 | 1356 | null 56722 | 3349 | null 57638 | 3364 | 3365 id |项目id |项目id | 1 ----: | --------: | --------: 56711 | 1974 |无效 56712 | 4220 | 4221 56721 | 1356 |空 56722 | 3349 |空 57638 | 3364 | 3365
您可以卸载json数组,将每个元素的最后4个字符作为一个数字,然后执行条件聚合:

select 
    id,
    max(val) filter(where rn = 1) item_id_1,
    max(val) filter(where rn = 2) item_id_2
from (
    select
        id,
        right(val, 4)::int val,
        dense_rank() over(partition by id order by right(val, 4)::int) rn
    from mytable t
    cross join lateral jsonb_array_elements_text(t.item_id -> 'itemID') as x(val)
) t
group by id
您可以向外部查询添加更多的条件
max()
s,以处理更多可能的值

id | item_id_1 | item_id_1 ----: | --------: | --------: 56711 | 1974 | null 56712 | 4220 | 4221 56721 | 1356 | null 56722 | 3349 | null 57638 | 3364 | 3365 id |项目id |项目id | 1 ----: | --------: | --------: 56711 | 1974 |无效 56712 | 4220 | 4221 56721 | 1356 |空 56722 | 3349 |空 57638 | 3364 | 3365


由于您无法动态选择列(您不知道将有多少个项目\u id\u X),我认为您应该使用unpivot/pivot,请参阅此处的示例,因为您无法动态选择列(您不知道将有多少个项目\u id\u X),我认为您应该使用unpivot/pivot,请参阅此处的示例