PSQL how to do math between JSONB fields? - jsonp

So I have table with "data" type JSONB column. I want do some calculations add/sub between values in the row. How I can do that?
psql> select 2 + ("data"->'field') - ("data"->'anotherField') from js_data_table;
This one produces an syntax error [42601].

Related

Postgresql query by json key condition

I've a table with JSON column and want to select rows where JSON key 'k' has value 'value'. Json may consist of several pairs of [K,V].
[
{"k":"esr:code","v":"800539"},
{"k":"lit","v":"yes"},
{"k":"name","v":"5 км"},
{"k":"railway","v":"halt"},
{"k":"uic_ref","v":"2040757"}
]
I tried to use the next query, but it's wrong.
SELECT *
FROM public.node
where ((node.tags)::json->>'k' like 'name')
How I can fix it, if it's possible?)
Where node - table name, tags - json column.
You can use the JSONB contains operator #>
SELECT *
FROM public.node
where node.tags #> '[{"k","name"}]';
This will do an exact match against name. Your usage of like might indicate you are looking for a partial match - however as your like condition doesn't use a wildcard it's the same as =.
This assumes that tags is defined as jsonb (which it should be). If it's not you need to cast it: node.tags::jsonb

Cannot use Where condition in Array columns

I have a column which is of an array type. I want to use the where condition in my script, but am unable to. The unnest formula is too complex to use and I want to keep it simple here.
I have 4 columns. One of them is called box_number. It can have an array of multiple numbers. I want to search for rows where box_number contains 123.
select
*
from BOX_TABLE
where box_number is {123}
ERROR: syntax error at or near "{"
SELECT * FROM BOX_TABLE WHERE 123 = ANY (box_number);
You check that at least one value inside the column is 123.
To test for equality, try
WHERE box_number = ARRAY[123]
To test if the array contains your value, use the “contains” operator &&:
WHERE box_number && ARRAY[123]

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)

Can SQL CASE return a different number of columns in WHEN clauses?

Is there a way to SELECT a different number of columns in different WHEN clauses of the same CASE statement?
For example
SELECT
CASE x
WHEN is y THEN show me 1 column
WHEN is z THEN show me 3 columns
END
FROM i;
The restriction is that all branches of the CASE expression must resolve to the same data type. The manual:
The data types of all the result expressions must be convertible to a
single output type. See Section 10.5 for more details.
If all your output columns have a compatible data type, you could use an ARRAY to include a variable number of columns (resulting in the same array type). Like:
SELECT CASE x
WHEN 1 THEN ARRAY[y]
WHEN 2 THEN ARRAY[x,y,z]
-- no ELSE defaults to NULL
END AS my_result_array
FROM tbl;
If not, you could cast to a common element type of your choice (text would be the safe default):
SELECT CASE x
WHEN 1 THEN ARRAY[x::text]
WHEN 2 THEN ARRAY[x::text, y::text, z::text]
END AS my_result_array
FROM tbl;
Or, to make it work for heterogeneous data types, you can use a composite type (row type) and pad with NULL values. Name, number and type of output columns are fixed and have to cover all possible result combinations.
CREATE TYPE foo (a int, b text, c date);
SELECT CASE x
WHEN 1 THEN (x, NULL, NULL)::foo
WHEN 2 THEN (x, y, z)::foo
END AS my_result_array
FROM tbl;
Or you could use a document type like json, hstore or xml to contain a variable number of column ...
Note that you get one result column either way, the workarounds just contain a variable payload - which can be decomposed in the next step.
No you can't since columns selection are static. If you really want to choose columns dynamically based on some condition then consider building a dynamic query for that purpose.

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