Я беру два массива JSONB, распаковываю их и прочесываю результаты. Я пытаюсь добавить WITH ORDINALITY
к распаковке массива JSON. Я не смог понять, как добавить WITH ORDINALITY
. По какой-то причине я не могу найти WITH ORDINALITY
в документации для инструментов JSON Postgres 11:
https://www.postgresql.org/docs/11/functions-json.html
Я видел примеры использования jsonb_array_elements....WITH ORDINALITY
, но не смог заставить его работать. Во-первых, функциональный пример на основе массивов Postgres:
WITH
first AS (
SELECT * FROM
UNNEST (ARRAY['Charles','Jane','George','Percy']) WITH ORDINALITY AS x(name_, index)
),
last AS (
SELECT * FROM
UNNEST (ARRAY['Dickens','Austen','Eliot']) WITH ORDINALITY AS y(name_, index)
)
SELECT first.name_ AS first_name,
last.name_ AS last_name
FROM first
JOIN last ON (last.index = first.index)
Это дает желаемый результат:
first_name last_name
Charles Dickens
Jane Austen
George Eliot
Я использую индекс ORDINALITY
для создания JOIN
, так как я объединяю два списка для попарного сравнения. Я могу предположить, что мои списки одинакового размера.
Однако мой ввод будет массивом JSON, а не массивом Postgres. У меня работает распаковка с jsonb_to_recordset
, но не работает генерация порядкового номера. Вот пример, который правильно выполняет распаковку:
DROP FUNCTION IF EXISTS tools.try_ordinality (jsonb, jsonb);
CREATE OR REPLACE FUNCTION tools.try_ordinality (
base_jsonb_in jsonb,
comparison_jsonb_in jsonb)
RETURNS TABLE (
base_text citext,
base_id citext,
comparison_text citext,
comparison_id citext)
AS $BODY$
BEGIN
RETURN QUERY
WITH
base_expanded AS (
select *
from jsonb_to_recordset (
base_jsonb_in)
AS base_unpacked (text citext, id citext)
),
comparison_expanded AS (
select *
from jsonb_to_recordset (
comparison_jsonb_in)
AS comparison_unpacked (text citext, id citext)
),
combined_lists AS (
select base_expanded.text AS base_text,
base_expanded.id AS base_id,
comparison_expanded.text AS comparison_text,
comparison_expanded.id AS comparison_id
from base_expanded,
comparison_expanded
)
select *
from combined_lists;
END
$BODY$
LANGUAGE plpgsql;
select * from try_ordinality (
'[
{"text":"Fuzzy Green Bunny","id":"1"},
{"text":"Small Gray Turtle","id":"2"}
]',
'[
{"text":"Red Large Special","id":"3"},
{"text":"Blue Small","id":"4"},
{"text":"Green Medium Special","id":"5"}
]'
);
Но это CROSS JOIN
base_text base_id comparison_text comparison_id
Fuzzy Green Bunny 1 Red Large Special 3
Fuzzy Green Bunny 1 Blue Small 4
Fuzzy Green Bunny 1 Green Medium Special 5
Small Gray Turtle 2 Red Large Special 3
Small Gray Turtle 2 Blue Small 4
Small Gray Turtle 2 Green Medium Special 5
Я получаю парный результат только с двумя строками:
Fuzzy Green Bunny 1 Red Large Special 3
Small Gray Turtle 2 Blue Small 4
Я попытался переключиться на jsonb_array_elements
, как в этом фрагменте:
WITH
base_expanded AS (
select *
from jsonb_array_elements (
base_jsonb_in)
AS base_unpacked (text citext, id citext)
),
Я вернусь
ERROR: a column definition list is only allowed for functions returning "record"
Есть ли простой способ получить порядковый номер в распакованном массиве JSON? Это очень просто с UNNEST
в массиве Postgres.
Я рад узнать, что испортил синтаксис.
Я могу
CREATE TYPE
, если это чем-то поможет.Я могу преобразовать в массив Postgres, если это просто сделать.
Спасибо за любые предложения.