postgres json array elements and null returns - sql

I have a json column in a table in postgres that includes an array of objects e.g.
{"BlockData":[{"Name":"George","Age":"54","Height":"1.75"}, {"Name":"Mario","Age":"35","Height":"1.90"}]}
I am using a Select query and want to access the Name object and the value pair of the Name (George and Mario). What I am trying to to is the following:
select jsonb_array_elements(jsondoc_->'BlockData')->>'Name' from BlockData;
What I get in return is
"ERROR: cannot extract elements from a scalar
SQL state: 22023"
From what I could discover is that this issue occurs because at some rows the return is NULL. Can you please advise how can I overlap this issue?

did you try to Filter them?
t=# with t(jsondoc_) as (values('{"BlockData":[{"Name":"George","Age":"54","Height":"1.75"}, {"Name":"Mario","Age":"35","Height":"1.90"}]}'::jsonb),('{"BlockData":null}'))
select jsonb_array_elements(jsondoc_->'BlockData')->>'Name' from t
where jsondoc_->'BlockData' <> 'null';
?column?
----------
George
Mario
(2 rows)

Related

How to cast postgres JSON column to int without key being present in JSON (simple JSON values)?

I am working on data in postgresql as in the following mytable with the fields id (type int) and val (type json):
id
val
1
"null"
2
"0"
3
"2"
The values in the json column val are simple JSON values, i.e. just strings with surrounding quotes and have no key.
I have looked at the SO post How to convert postgres json to integer and attempted something like the solution presented there
SELECT (mytable.val->>'key')::int FROM mytable;
but in my case, I do not have a key to address the field and leaving it empty does not work:
SELECT (mytable.val->>'')::int as val_int FROM mytable;
This returns NULL for all rows.
The best I have come up with is the following (casting to varchar first, trimming the quotes, filtering out the string "null" and then casting to int):
SELECT id, nullif(trim('"' from mytable.val::varchar), 'null')::int as val_int FROM mytable;
which works, but surely cannot be the best way to do it, right?
Here is a db<>fiddle with the example table and the statements above.
Found the way to do it:
You can access the content via the keypath (see e.g. this PostgreSQL JSON cheatsheet):
Using the # operator, you can access the json fields through the keypath. Specifying an empty keypath like this {} allows you to get your content without a key.
Using double angle brackets >> in the accessor will return the content without the quotes, so there is no need for the trim() function.
Overall, the statement
select id
, nullif(val#>>'{}', 'null')::int as val_int
from mytable
;
will return the contents of the former json column as int, respectvely NULL (in postgresql >= 9.4):
id
val_int
1
NULL
2
0
3
2
See updated db<>fiddle here.
--
Note: As pointed out by #Mike in his comment above, if the column format is jsonb, you can also use val->>0 to dereference scalars. However, if the format is json, the ->> operator will yield null as result. See this db<>fiddle.

get all the json object with a specified conditions

I have a jsonarray as given below
[{"key1":10},{"key1":20},{"key1":30}]
I want to get all the json objects with a specified condition. say get all the json objects with key1 less than 25. so my sql query should return this list
[{"key1":10},{"key1":20}]
what is the resultant SQL query for this.
step-by-step demo:db<>fiddle
SELECT
json_agg(elements) -- 3
FROM mytable,
json_array_elements(mydata) as elements -- 1
WHERE (elements ->> 'key1')::int < 25 -- 2
Extract the JSON array: Each element is now in an own record
Filter by the value. Notice, that ->> returns a type text, so you need to cast it into type int in your case
Reaggregate the remaining elements into the new array
If you are using Postgres 12 or later you can use a JSON path function:
select jsonb_path_query_array(the_column, '$[*] ? (#.key1 <= 25)')
from the_table
Online example

compare input array and data from postgres table - find which are the same

For example I have array of names:
['andrew','vasya','oleg']
Also I have some data into db:
name age id
andrey 12 23432
andrew 13 32432
I want to check by one request get all values which exist in db with the same name as in array . It should return me ['andrew'] response. It means that in my array exist one the same value as in column name into db. Can I make it?
I can make it in next way: get all values from db and compare it by using some kind of sorting loop, but it will be slow.
You can use the = ANY operator for that:
select *
from the_table
where name = any (array['andrew','vasya','oleg'] );

JSONB column query

There is a JSONB column (some_strings) that has value like string array
---------------------
["string1","string2","string3"]
["string5"]
["string6","string7"]
-------etc-----------
Is there a way to make a query to get row where (some_strings) contain "string2" ?
This query will return records where string2 appears anywhere in the JSONB array:
SELECT *
FROM yourTable
WHERE some_strings ?& array['string2']
Documentation

SQL: how to return nth value from json in postgresql

I am trying to SELECT and parse a javascript list in a postgres table column, it has no keys:
{coastal,transitional,contemporary,romantic,traditional,
industrial,modern,contemporary_eclectic,regency,mediterranean}
What SQL command get's the nth value?
I know you can get values by key like this:
SELECT {column_name}->>{key value}
FROM {table_name}
But I really want to just pull values by list-value order. Is there some syntax that I cannot find? Or do I need to transform this array into a different data type?
The same actually works for arrays:
{column_name}->>N
where N is the integer position of an element.
References:
https://www.postgresql.org/docs/current/static/functions-json.html
Turns out I asked the wrong question--I have a postgres array, not a JSON:
I was struggling because posgres starts counting arrays at position 1, not 0--doh!
{column_name}[1] //this is the first value in the array