如何以特定顺序连接JSON数组的两个值?

时间:2019-06-04 13:06:16

标签: arrays json postgresql concatenation aggregate

我正在使用PostgreSQL 9.5。我有一个带有JSON数组的表,其中包含以下格式的JSON对象:

[]
[{animal:cat}, {plant:sunflower}, {car:mercedes}]
[{animal:dog}]
[{animal:dog}, {car:audi}]
[]

我需要输出一个组合了 animal plant 的值的表,然后计算每个键值组合的数量。空值需要忽略,但是只有动物植物的情况也被分组为自己的组。 汽车需要完全移除。

我理想的最终结果类似于:

Animal : Plant     |  Amount
---------------------------
cat : oak          |   54
cat : sunflower    |   127
dog                |   8
cow : oak          |   3
...

我尝试过的事情:

SELECT
    ((json_array_elements(Table.json_array)::JSONB
- 'car')::JSON#>>'{animal}')::TEXT AS elems,
    count(*)
FROM    Table
GROUP BY elems

我可以看到这给了我 animal 作为字符串,并对它的每个实例进行了计数。我还可以通过将JSON数组转换为JSONB来删除 car ,然后使用减号运算符将 car 删除,然后再转换回JSON。强制转换为JSONB会改变我的值顺序。

但是当我尝试将 animal plant 中的字符串连接起来时:

SELECT
    (((json_array_elements(Table.json_array))::JSON#>>'{animal}') || ' : ' || ((json_array_elements(Table.json_array))::JSON#>>'{plant}'))
    ::TEXT AS elems,
    count(*)
FROM    Table
GROUP BY elems

我收到错误消息:

  

函数和运算符最多可以使用一组参数

尝试json_aggCONCAT()||,结果相同。

我试图弄清楚如何将动物植物的一面浇铸成一组,但到目前为止没有进展。

如何获得理想的结果?当我通过数据可视化程序Apache超集使用数据库时,我只能使用Postgres命令。

1 个答案:

答案 0 :(得分:3)

一种方法:

SELECT animal_plant, count(*)
FROM  (
   SELECT t.id, concat_ws(' : '
                        , string_agg(elem ->> 'animal', '|')
                        , string_agg(elem ->> 'plant' , '|')) AS animal_plant
   FROM   tbl t, json_array_elements(t.json_array) j(elem)
   GROUP  BY t.id
   ) sub
GROUP  BY 1
ORDER  BY 1;

这将来自同一JSON值的所有猫和所有狗串联起来,因为您没有透露是否可以有多个。 (如果每个最多有一个,它会产生您想要的结果。)

db <>提琴here

在Postgres 12中使用SQL / JSON可能会变得更简单...
(无论如何,您都需要尽快升级到现代版本的Postgres。)