我以一种有点奇怪的方式存储了数据,但是我必须对此进行处理。以下示例表示其结构:
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":[] }]');
我设法提取了所需的数据,可能不是以最优雅的方式,但是输出是我所需的ALMOST。
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
和null
列中都缺少amount
和price
的记录。如果价格和金额都缺失,为什么结果从结果中消失,而如果其中之一缺失,则给出空值?
@@我找到了原因,如果数组详细信息为空,则不再包含json。但是仍然idk如何克服它。
理想情况下,我想使用coalesce
并将其放置在1
中,如果它为null,但它给出一个]
ERROR: set-returning functions are not allowed in COALESCE
我该如何解决?
Set返回函数应在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