Конвертировать jsonb в PostgreSQL в строки без цикла - PullRequest
0 голосов
/ 22 декабря 2018

ff У меня есть массив json, хранящийся в моей базе данных postgres.Первая таблица «Orders» выглядит следующим образом:

order_id, basket_items_id
1, {1,2}
2, {3}
3, {1,2,3,1}

Вторая таблица «Items» выглядит следующим образом:

item_id, price
1,5
2,3
3,20

Уже пытались загрузить данные с несколькими sql и выбрать разные jsonbзапись, но это не серебряная пуля.

SELECT
sum(price)
FROM orders
INNER JOIN items on
orders.basket_items_id = items.item_id
WHERE order_id = 3;

Хотите получить это как вывод:

order_id, basket_items_id, price
1, 1, 5
1, 2, 3
2, 3, 20
3, 1, 5
3, 2, 3
3, 3, 20
3, 1, 5

или это:

order_id, sum(price)
1, 8
2, 20
3, 33

Ответы [ 2 ]

0 голосов
/ 22 декабря 2018

demo: db <> fiddle

SELECT
    o.order_id,
    elems.value::int as basket_items_id,
    i.price
FROM
    orders o, jsonb_array_elements_text(basket_items_id) as elems
LEFT JOIN items i 
ON i.item_id = elems.value::int
ORDER BY 1,2,3
  1. jsonb_array_elements_text расширяет массив jsonb в одну строку каждого элемента.Благодаря этому вы можете соединиться со своей второй таблицей напрямую
  2. Поскольку расширенный массив дает вам text элементов, вы должны преобразовать их в целые числа, используя ::int

КонечноВы можете GROUP и SUM агрегировать это также:

SELECT
    o.order_id,
    SUM(i.price)
FROM
    orders o, jsonb_array_elements_text(basket_items_id) as elems
LEFT JOIN items i 
ON i.item_id = elems.value::int
GROUP BY o.order_id
ORDER BY 1
0 голосов
/ 22 декабря 2018

Ваш orders.basket_items_id столбец типа jsonb или int[]?

Если тип jsonb, вы можете использовать json_array_elements_text для расширения столбца:

SELECT
    o.order_id,
    o.basket_item_id,
    items.price
FROM
(
    SELECT
        order_id,
        jsonb_array_elements_text(basket_items_id)::int basket_item_id
    FROM
        orders
) o
JOIN
    items ON o.basket_item_id = items.item_id
ORDER BY
    1, 2, 3;

См. эту DB-Fiddle .

Если типом является int[] (массив целых чисел), вы можете выполнить аналогичный запрос с помощью unnest функция:

SELECT
    o.order_id,
    o.basket_item_id,
    items.price
FROM
(
    SELECT
        order_id,
        unnest(basket_items_id) basket_item_id
    FROM
        orders
) o
JOIN
    items ON o.basket_item_id = items.item_id
ORDER BY 
    1, 2, 3;

См. эту DB-скрипку

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...