在 Postgres 11.7 中将 ORDINALITY 添加到扩展的 JSON 数组
Add ORDINALITY to expanded JSON array in Postgres 11.7
我正在使用两个 JSONB 数组,将它们解包,然后组合结果。我正在尝试将 WITH ORDINALITY
添加到 JSON 数组解包中。我一直想不出如何添加 WITH ORDINALITY
。出于某种原因,我在 Postgres 11 的 JSON 工具的文档中找不到 WITH ORDINALITY
:
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 数组的序数?在 Postgres 数组上使用 UNNEST
非常容易。
很高兴得知我搞砸了语法。
我可以CREATE TYPE
,如果有帮助的话。
我可以转换为 Postgres 数组,如果这样做很简单的话。
感谢您的任何建议。
你做的完全一样。
with first as (
select *
from jsonb_array_elements('[
{"text":"Fuzzy Green Bunny","id":"1"},
{"text":"Small Gray Turtle","id":"2"}
]'::jsonb) with ordinality as f(element, idx)
), last as (
select *
from jsonb_array_elements('[
{"text":"Red Large Special","id":"3"},
{"text":"Blue Small","id":"4"},
{"text":"Green Medium Special","id":"5"}
]'::jsonb) with ordinality as f(element, idx)
)
SELECT first.element ->> 'text' AS first_name,
last.element ->> 'text' AS last_name
FROM first
JOIN last ON last.idx = first.idx
我正在使用两个 JSONB 数组,将它们解包,然后组合结果。我正在尝试将 WITH ORDINALITY
添加到 JSON 数组解包中。我一直想不出如何添加 WITH ORDINALITY
。出于某种原因,我在 Postgres 11 的 JSON 工具的文档中找不到 WITH ORDINALITY
:
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 数组的序数?在 Postgres 数组上使用 UNNEST
非常容易。
很高兴得知我搞砸了语法。
我可以
CREATE TYPE
,如果有帮助的话。我可以转换为 Postgres 数组,如果这样做很简单的话。
感谢您的任何建议。
你做的完全一样。
with first as (
select *
from jsonb_array_elements('[
{"text":"Fuzzy Green Bunny","id":"1"},
{"text":"Small Gray Turtle","id":"2"}
]'::jsonb) with ordinality as f(element, idx)
), last as (
select *
from jsonb_array_elements('[
{"text":"Red Large Special","id":"3"},
{"text":"Blue Small","id":"4"},
{"text":"Green Medium Special","id":"5"}
]'::jsonb) with ordinality as f(element, idx)
)
SELECT first.element ->> 'text' AS first_name,
last.element ->> 'text' AS last_name
FROM first
JOIN last ON last.idx = first.idx