在 json 中使用 coalesce 设置返回函数

Use coalesce in json set returning function

我有一个数据以有点奇怪的方式存储,但我必须解决这个问题。以下示例表示其结构:

https://www.db-fiddle.com/f/rAALhAatyedGgXK5LxvLeG/3

create table tickets
(ticket_id integer,
 properties text);

 insert into tickets
 values
 (123,'[{"details":[
{"amount":"5","price":150},
{"amount":"2","price":200}]}]'),

(124,'[{"details":[
{"price":430}
]}]'),

(125,'[{"details":[] }]');

我设法提取了所需的数据,可能不是以最优雅的方式,但输出是 几乎 我需要的。

SELECT 
ticket_id,
REPLACE((json_array_elements(json_array_elements(properties::json)->'details')->'amount')::TEXT, '"','')::int as amount,
((json_array_elements(json_array_elements(properties::json)->'details')->'price')::text)::int AS price
FROM tickets

ticket_id   amount  price
123         5       150
123         2       200
124         null    430

缺少的记录是 ticket 125,在 amountprice 列中都有 null。为什么如果价格和金额都缺失但结果中没有结果,但如果只缺失其中一个则返回 null?

@edit 我找到原因了,如果数组 details 是空的,它不再包含 json。但仍然不知道如何克服它。

理想情况下,我想使用 coalesce 并放在那里 1 如果它为 null 但它给出

ERROR:  set-returning functions are not allowed in COALESCE

我该如何解决?

应在 FROM 子句中使用设置返回函数。

要包含 id = 125 的行(带有空数组),您需要对 jsonb_array_elements() 函数使用外部联接,以便包含其结果为空的行。

SELECT ticket_id, 
       (d.detail ->> 'price')::int as price,
       (d.detail ->> 'amount')::int as amount
FROM tickets
  left join jsonb_array_elements( ((properties::Jsonb) -> 0) -> 'details' ) as d(detail) on true

Online example