Хорошо, если вы
SELECT jsonb_array_elements(summary->'users') as users FROM orders;
вы получите
┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ users │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ {"food": [{"name": "dinner", "price": "100"}, {"name": "breakfast", "price": "50"}], "room": "2", "user": "bob"} │
│ {"room": "3", "user": "foo"} │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Давайте поставим этот выбор внутри другой, выбирая то, что нам нужно:
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) │
└───────────┴──────────┘
Мы близки. Нам просто нужно добавить 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;
Результирующее в
┌───────────┬──────────┐
│ user_name │ food │
├───────────┼──────────┤
│ "bob" │ "dinner" │
└───────────┴──────────┘
Если у вас есть данные в массиве еды как
'{"users": [{"food": [{"name": "dinner", "price": "100"}, {"name" : "breakfast", "price" : "50"}], "room": "2", "user": "bob"}, {"room": "3", "user": "foo"}]}'
Вы можете сделать
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;
И
┌───────────┬───────────┐
│ user_name │ food │
├───────────┼───────────┤
│ "bob" │ dinner │
│ "bob" │ breakfast │
└───────────┴───────────┘
Переписывая выше запрос использовать Common Table Expressions
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;
Теперь нам нужно сгруппировать по 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;
Окончательный результат
┌───────────┬────────────────────┐
│ user_name │ foods │
├───────────┼────────────────────┤
│ "bob" │ {dinner,breakfast} │
└───────────┴────────────────────┘
Это лучшее, что я мог бы придумайте. Дайте мне знать, если вы найдете лучший способ.
Это здорово !, если в еде есть еще несколько элементов, таких как «еда»: [{«name»: «test1», «price»: «100»}, {«name»: «завтрак», «цена» ":" 10 "}]' –
@StefanMielke отредактировал –
Отлично! что это разрешило –