我有一个订单表,我在jsonb
列中存储订单摘要
{"users": [
{"food": [{"name": "dinner", "price": "100"}], "room": "2", "user": "bob"},
{"room": "3", "user": "foo"}
]}
Run Code Online (Sandbox Code Playgroud)
现在我想users
用他们的查询全部food->name
.
我尝试了以下,但这也给了我用户foo,没有食物.
select
jsonb_array_elements(jsonb_array_elements(summary->'users')->'food')->>'name' as food,
jsonb_array_elements(summary->'users')->>'user' as user_name
from orders;
food | user_name
-------+-----------
dinner | bob
dinner | foo
Run Code Online (Sandbox Code Playgroud)
我该怎么做这样的查询?
UPDATE
我还有两个食物选择这样的夏季
{"users": [
{"food": [{"name": "dinner", "price": "100"}, {"name": "breakfast", "price": "100"}], "room": "2", "user": "bob"},
{"room": "3", "user": "foo"}
]}
Run Code Online (Sandbox Code Playgroud)
而不是我得到:
food | user_name
-----------+-----------
dinner | bob
breakfast | foo
Run Code Online (Sandbox Code Playgroud)
理想情况下我想得到
food | user_name
----------------------+-----------
dinner, breakfast | bob
Run Code Online (Sandbox Code Playgroud)
好的,如果你这样做的话
SELECT jsonb_array_elements(summary->'users') as users FROM orders;
Run Code Online (Sandbox Code Playgroud)
你得到
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
? users ?
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
? {"food": [{"name": "dinner", "price": "100"}, {"name": "breakfast", "price": "50"}], "room": "2", "user": "bob"} ?
? {"room": "3", "user": "foo"} ?
????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
让我们把这个选择放在另一个,选择我们需要的:
SELECT users->'user' as user_name, users->'food'->0->'name' as food FROM (
SELECT jsonb_array_elements(summary->'users') as users FROM orders
) as s;
????????????????????????
? user_name ? food ?
????????????????????????
? "bob" ? "dinner" ?
? "foo" ? (null) ?
????????????????????????
Run Code Online (Sandbox Code Playgroud)
我们很接近.我们只需要添加一个WHERE
.
SELECT users->'user' as user_name, users->'food'->0->'name' as food FROM (
SELECT jsonb_array_elements(summary->'users') as users FROM orders
) as s WHERE (users->'food') is not null;
Run Code Online (Sandbox Code Playgroud)
导致
????????????????????????
? user_name ? food ?
????????????????????????
? "bob" ? "dinner" ?
????????????????????????
Run Code Online (Sandbox Code Playgroud)
如果食物阵列中有更多数据,例如
'{"users": [{"food": [{"name": "dinner", "price": "100"}, {"name" : "breakfast", "price" : "50"}], "room": "2", "user": "bob"}, {"room": "3", "user": "foo"}]}'
Run Code Online (Sandbox Code Playgroud)
你可以做
SELECT users->'user' as user_name, jsonb_array_elements(users->'food')->>'name' as food FROM (
SELECT jsonb_array_elements(summary->'users') as users FROM orders
) as s WHERE (users->'food') is not null;
Run Code Online (Sandbox Code Playgroud)
和
?????????????????????????
? user_name ? food ?
?????????????????????????
? "bob" ? dinner ?
? "bob" ? breakfast ?
?????????????????????????
Run Code Online (Sandbox Code Playgroud)
重写上述查询以使用公用表表达式
WITH users_data AS (
SELECT jsonb_array_elements(summary->'users') as users FROM orders
), user_food AS (
SELECT users->'user' as user_name, jsonb_array_elements(users->'food')->>'name' as food
FROM users_data
WHERE (users->'food') is not null
) SELECT * FROM user_food;
Run Code Online (Sandbox Code Playgroud)
现在我们只需要分组 user_name
WITH users_data AS (
SELECT jsonb_array_elements(summary->'users') as users FROM orders
), user_food AS (
SELECT users->'user' as user_name, jsonb_array_elements(users->'food')->>'name' as food
FROM users_data
WHERE (users->'food') is not null
) SELECT user_name, array_agg(food) foods FROM user_food GROUP BY user_name;
Run Code Online (Sandbox Code Playgroud)
最后结果
??????????????????????????????????
? user_name ? foods ?
??????????????????????????????????
? "bob" ? {dinner,breakfast} ?
??????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
这是我能想到的最好的.如果你找到更好的方法,请告诉我.
归档时间: |
|
查看次数: |
821 次 |
最近记录: |