I am quite struggling to make a SQL request to fit my need. I have like the following data:
id attribute
1 {"a":["b",["b","c"],["e","f","g"]]}
2 {"b":true}
Thus attribute is a json field with a non unique schema. What I am trying to have as an output is the following:
id attribute
1 ["b","b.c","e.f.g"]
2 true
So far I have some complex SQL query (in my opinion) that barrely do the job:
WITH temp AS (
SELECT
id,
string_to_array(attribute -> 'a',',') as bar,
array_agg( array(
SELECT string_agg(val, '.')
FROM jsonb_array_elements_text(item) AS val
)) as foo
FROM test
LEFT JOIN jsonb_array_elements(attribute -> 'b') AS item ON TRUE
GROUP BY 1,2
)
SELECT id, replace(coalesce(bar,NULLIF(foo, '{{NULL}}')),'true','all')
FROM temp;
Thank you for help.
I am quite struggling to make a SQL request to fit my need. I have like the following data:
id attribute
1 {"a":["b",["b","c"],["e","f","g"]]}
2 {"b":true}
Thus attribute is a json field with a non unique schema. What I am trying to have as an output is the following:
id attribute
1 ["b","b.c","e.f.g"]
2 true
So far I have some complex SQL query (in my opinion) that barrely do the job:
WITH temp AS (
SELECT
id,
string_to_array(attribute -> 'a',',') as bar,
array_agg( array(
SELECT string_agg(val, '.')
FROM jsonb_array_elements_text(item) AS val
)) as foo
FROM test
LEFT JOIN jsonb_array_elements(attribute -> 'b') AS item ON TRUE
GROUP BY 1,2
)
SELECT id, replace(coalesce(bar,NULLIF(foo, '{{NULL}}')),'true','all')
FROM temp;
Thank you for help.
If you need just "the first property of the top-level object", then:
select
id,
attribute->>((array(select jsonb_object_keys(attribute)))[1]) attribute
from test;
If you have a more complex handling (choose one path for objects having a
, else another one), add some case
s.
(from PostgreSQL 14, see in a fiddle)
(greatly inspired from another SO question from 2016)
a
andb
properties? – Charlieface Commented Feb 11 at 14:59