【问题标题】:PostgreSQL aggregate over json arraysPostgreSQL 在 json 数组上聚合
【发布时间】:2022-08-16 07:07:29
【问题描述】:

我已经看到很多关于使用 json_array_elements 提取 JSON 数组元素的参考资料。但是,这似乎仅适用于 1 个数组。如果我在通用查询中使用它,我会收到错误

ERROR: cannot call json_array_elements on a scalar

鉴于这样的事情:

orders
{ \"order_id\":\"2\", \"items\": [{\"name\": \"apple\",\"price\": 1.10}]}
{ \"order_id\": \"3\",\"items\": [{\"name\": \"apple\",\"price\": 1.10},{\"name\": \"banana\",\"price\": 0.99}]}

我想提取

item count
apple 2
banana 1

或者

item total_value_sold
apple 2.20
banana 0.99

是否可以使用 json_array_elements 聚合这样的 json 数组?

  • \"这似乎只适用于 1 个数组。如果我在通用查询中使用它\" - 不知道你的意思。你能告诉我们你使用的代码,导致错误的代码吗?

标签: arrays json postgresql aggregate-functions jsonb


【解决方案1】:

使用orders->'items' 的函数来展平数据:

select elem->>'name' as name, (elem->>'price')::numeric as price
from my_table
cross join jsonb_array_elements(orders->'items') as elem;

从展平的数据中很容易得到你想要的聚合:

select name, count(*), sum(price) as total_value_sold
from (
    select elem->>'name' as name, (elem->>'price')::numeric as price
    from my_table
    cross join jsonb_array_elements(orders->'items') as elem
    ) s
group by name;

Db<>fiddle.

【讨论】:

  • 当我运行你的小提琴时,它工作正常 - 但是当我用 WITH ( VALUES ...) 换出 WITH (SELECT * FROM my_local_table) 时,它会抛出同样的错误
  • 你怎么这样称呼表名? orders->'items' 对我来说真的没有意义,因为它不是列名。我正在使用您的语法(没有小提琴中的 WITH)在我的本地表上尝试它,它说 ERROR: column "orders" does not exist
  • 我查询中的orders 是列名。将其替换为您忘记包含在问题中的实际 jsonb 列名称。
  • 对,对不起,问题最终实际上是数据中有空值数组。您的回答有效,关键是还要添加 WHERE orders->>items IS NOT NULL
猜你喜欢
  • 2017-09-28
  • 1970-01-01
  • 2012-06-11
  • 1970-01-01
  • 1970-01-01
  • 2021-09-24
  • 2022-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多