Search strings in json array column - sql

I have this PostgreSQL table:
id | something
1 | ["something1", "something2", "something3"]
2 | ["something1"]
3 | ["something2", "something4"]
I am using this query to get all the datas having the string something1 in the something column:
select * from my_table where (something)::jsonb ? 'something1'
How can i modify (or also there's a better way) this query to get all the datas that contains something1 OR something2?

You can use ?:
where something::jsonb ? 'something1'
To check for several possible values, use ?| against a text array:
where something::jsonb ?| array['something1', 'something2']
This checks if any value from the array exists in the jsonb array. If you want to check if all array elements exist in the jsonb payload, then use ?& instead.

Related

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

how to convert array elements from string to int in postgres?

I have a column in the table as jsonb [14,21,31]
and I want to get all the rows with selected element eg
SELECT *
FROM t_customers
WHERE tags ?| array['21','14']
but the jsonb elements are in integer format
how do i convert the sql array elements into integer
i tried removing the quotes from the array but it gives an error
A naive solution would be:
t=# with t_customers(tags) as (values('[14,21,31]'::jsonb))
select
tags
, translate(tags::text,'[]','{}')::int[] jsonb_int_to_arr
, translate(tags::text,'[]','{}')::int[] #> array['21','14']::int[] includes
from
t_customers;
tags | jsonb_int_to_arr | includes
--------------+------------------+----------
[14, 21, 31] | {14,21,31} | t
(1 row)
https://www.postgresql.org/docs/current/static/functions-array.html
if you want to cast as array - you should use #> operator to check if contains.
(at first I proposed it because I misunderstood the question - so it goes the opposite way, "turning" jsonb to array and checking if it contains, but now maybe this naive approach is the shortest)
the right approach here probably would be:
t=# with t_customers(tags) as (values('[14,21,31]'::jsonb))
, t as (select tags,jsonb_array_elements(tags) from t_customers)
select jsonb_agg(jsonb_array_elements::text) ?| array['21','14'] tags from t group by tags;
tags
------
t
(1 row)
which is basically "repacking" jsonb array with text representations of integers

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'] );

postgres json array elements and null returns

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)

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