我正在使用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_agg
,CONCAT()
和||
,结果相同。
我试图弄清楚如何将动物或植物的一面浇铸成一组,但到目前为止没有进展。
如何获得理想的结果?当我通过数据可视化程序Apache超集使用数据库时,我只能使用Postgres命令。
答案 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。)