Reputation: 190
I have a column in the table which stores polygon points in jsonb,
position
---------------
[{"x": 455, "y": -3165},{"x": 455,"y": 50}, {"x": 5708,"y": 50}]
I want to turn the jsonb into array, like this:
position_array
-----------------
((455, -3165),(455, 50), (5708, 50))
I can't figout a simple way to do this. Pls help
Upvotes: 2
Views: 4874
Reputation: 23676
SELECT
array_agg( -- 4
ARRAY[ -- 3
(elems -> 'x')::int,
(elems -> 'y')::int -- 2
]
)
FROM
t,
jsonb_array_elements(data) as elems -- 1
x
/y
valuesx
/y
into an arrayUpvotes: 1
Reputation: 701
You should use the jsonb_to_recordset(jsonb)
function, from the official PostgreSQL docs
To quote the docs:
Expands the top-level JSON array of objects to a set of rows having the composite type defined by an AS clause
In this case, we need to apply jsonb_to_recordset
to the actual jsonb itself. This will allow postgres to think about your jsonb array as a set of rows that follow a composite type definition, which is defined by AS (x int, y int)
in your case. This tells postgres that, once it has finished transforming the jsonb
into a recordset, it should pluck out the x
and y
keys in your jsonb
and treat them as integers.
You can read more about composite types here
That looks like this (I simply copied and pasted your raw jsonb in here):
jsonb_to_recordset('[{"x": 455, "y": -3165},{"x": 455,"y": 50}, {"x": 5708,"y": 50}]') AS position(x int, y int);
If you run:
SELECT * FROM jsonb_to_recordset('[{"x": 455, "y": -3165},{"x": 455,"y": 50}, {"x": 5708,"y": 50}]') AS (x int, y int);
You'll see that it gives you 3 rows with columns x
and y
containing the expected values from each object in your jsonb
.
Next, you're going to want to use array_agg
to turn this into your final desired array. However, you'll need to specify that what you want to aggregate is actually array[x, y]
-- this will effectively aggregate an array of arrays with shape {x, y}
, where x
and y
are both ints coming from your composite type AS (x int, y int)
.
Putting it all together, this should give you the desired result:
SELECT array_agg(array[x, y]) as position_array FROM jsonb_to_recordset('[{"x": 455, "y": -3165},{"x": 455,"y": 50}, {"x": 5708,"y": 50}]') AS (x int, y int);
Outputting:
{{455,-3165},{455,50},{5708,50}}
Just a quick note: in Postgres, arrays are defined with {
instead of (
:)
Upvotes: 2