首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >仅从Postgres JSONB对象数组访问(并计数)对象值

仅从Postgres JSONB对象数组访问(并计数)对象值
EN

Stack Overflow用户
提问于 2018-05-17 15:13:39
回答 1查看 542关注 0票数 1

我在Postgres数据库中有一个JSONB列。我正在存储一个JSON对象数组,每个对象都有一个键值对。我相信我本可以设计得更好,但现在我被困在这里了。

代码语言:javascript
复制
id | reviews
------------------
 1 | [{"apple": "delicious"}, {"kiwi": "not-delicious"}]
 2 | [{"orange": "not-delicious"}, {"pair": "not-delicious"}]
 3 | [{"grapes": "delicious"}, {"strawberry": "not-delicious"}, {"carrot": "delicious"}]

假设这个表名为tasks。虽然这些对象中的键是不可预测的,但是值是可预测的。对于每一行,我想知道reviews数组中“美味”和“不好吃”值的数量。

编辑以求澄清:

我正在寻找上表中每个id/row的美味/非美味计数。所需样本输出:

代码语言:javascript
复制
id | delicious | not_delicious
-------------------------------
 1 |         1 |             1
 2 |         0 |             2
 3 |         2 |             1
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-17 15:22:05

假设r是您的桌子:

代码语言:javascript
复制
so=# select * from r;
                                       reviews
-------------------------------------------------------------------------------------
 [{"apple": "delicious"}, {"kiwi": "not-delicious"}]
 [{"orange": "not-delicious"}, {"pair": "not-delicious"}]
 [{"grapes": "delicious"}, {"strawberry": "not-delicious"}, {"carrot": "delicious"}]
(3 rows)

然后:

代码语言:javascript
复制
so=# with j as (select jsonb_array_elements(reviews) a, r, ctid from r)
select jsonb_object_keys(a), a->>jsonb_object_keys(a),ctid from j;
 jsonb_object_keys |   ?column?    | ctid
-------------------+---------------+-------
 apple             | delicious     | (0,1)
 kiwi              | not-delicious | (0,1)
 orange            | not-delicious | (0,2)
 pair              | not-delicious | (0,2)
 grapes            | delicious     | (0,3)
 strawberry        | not-delicious | (0,3)
 carrot            | delicious     | (0,3)
(7 rows)

我使用ctid作为行标识符,因为我没有其他列,并且不需要长reviews

显然,每一行都有美味的聚合:

代码语言:javascript
复制
so=# with j as (select jsonb_array_elements(reviews) a, r, ctid from r)
select ctid, a->>jsonb_object_keys(a), count(*) from j group by a->>jsonb_object_keys(a),ctid;
 ctid  |   ?column?    | count
-------+---------------+-------
 (0,1) | delicious     |     1
 (0,3) | delicious     |     2
 (0,1) | not-delicious |     1
 (0,2) | not-delicious |     2
 (0,3) | not-delicious |     1
(5 rows)

用于更新post

代码语言:javascript
复制
so=# with j as (select jsonb_array_elements(reviews) a, r, ctid from r)
, n as (
 select ctid,a->>jsonb_object_keys(a) k from j
)
, ag as (
select ctid
, case when k = 'delicious' then 1 else 0 end deli
, case when k = 'not-delicious' then 1 else 0 end notdeli
from n
)
select ctid, sum(deli) deli, sum(notdeli) notdeli from ag group by ctid;
 ctid  | deli | notdeli
-------+------+---------
 (0,1) |    1 |       1
 (0,2) |    0 |       2
 (0,3) |    2 |       1
(3 rows)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50394928

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档