ERROR 42883: operator does not exist: text / text - postgresql

When running the following query:
select data from example
where (data -> 'properties' ->> 'outageCount') / (data -> 'properties' ->> 'trackedCount') > 0.01
I'm getting the following error:
ERROR 42883: operator does not exist: text / text
Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Both outageCount and trackedCount are stored as integers in the JSONB.
I tried casting using as float but it gave following error:
[42601] ERROR: syntax error at or near "as"

Even if the field is a JSON number, it will be returned as text (see json and jsonb operators):
db=# select pg_typeof(('{"foo":3}'::jsonb)->>'foo');
pg_typeof
-----------
text
(1 row)
You need to cast it by appending ::float to the expression:
db=# select pg_typeof((('{"foo":3}'::jsonb)->>'foo')::float);
pg_typeof
------------------
double precision
(1 row)
In your case:
select data from example
where (data -> 'properties' ->> 'outageCount')::float / (data -> 'properties' ->> 'trackedCount')::float > 0.01

Related

How to add/subtract an integer to an array of integers?

select
array[100,200,300]-100
My expectation was to get [0,100,200].
I got this error:
ERROR: operator does not exist: integer[] - integer Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts. Position: 26
How can I fix it?
You can use a combination of array functions: unnest and array_agg:
postgres=# SELECT array_agg(val-100) as arr FROM unnest(array[100,200,300]) as val;
arr
-------------
{0,100,200}
(1 row)

How can I convert a jsonb nested string field to int in postgresql?

I am using postgresql 11 and I have a jsonb field.
amount
----------------------------------------
{"value": "3590", "currency": "AUD"}
I can use this syntax to select the nested field value: select amount->'value'.
but I don't know how I can convert it to integer and sum it, like select sum(amount->'value') from
I got this error: HINT: No function matches the given name and argument types. You might need to add explicit type casts.
I tried to convert it by
select sum(amount->'value')::DECIMAL
select sum(TO_NUMBER(amount->'value'))
but none of them working. What is the correct way to do that?
Use the ->> operator to get the value as text:
https://www.postgresql.org/docs/11/functions-json.html
SELECT SUM((amount->>'value')::INT)

Postgres jsonb : cast array element to integer

Using Postgres 11.2.9 (ubuntu),
In my database, I have a jsonb field containing values that look like this :
[1618171589133, 1618171589245, 1618171589689]
I'd like to retrieve rows where the first element is lower than a specific value. I've tried this :
SELECT * FROM user.times WHERE time ->> 0 < 1618171589133
but I get the following error : ERROR: operator does not exist: text = bigint
Should I somehow cast the time value to numeric value ? I've tried time ->> 0::numeric but I actually don't know what to do.
The ->> operator returns the element at given position as text, which you can then convert to integer (or as it seems in this case, bigint), as you would normally do in postgres, using the :: as suffix.
SELECT * FROM user.times WHERE ((time ->> 0)::bigint) < 1618171589133

Postgres: create index on attribute of attribute in JSONB column?

I'm working in Postgres 9.6.5. I have the following table:
id | integer
data | jsonb
The data in the data column is nested, in the form:
{ 'identification': { 'registration_number': 'foo' }}
I'd like to index registration_number, so I can query on it. I've tried this (based on this answer):
CREATE INDEX ON mytable((data->>'identification'->>'registration_number'));
But got this:
ERROR: operator does not exist: text ->> unknown
LINE 1: CREATE INDEX ON psc((data->>'identification'->>'registration... ^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
What am I doing wrong?
You want:
CREATE INDEX ON mytable((data -> 'identification' ->> 'registration_number'));
The -> operator returns the jsonb object under the key, and the ->> operator returns the jsonb object under the key as text. The most notable difference between the two operators is that ->> will "unwrap" string values (i.e. remove double quotes from the TEXT representation).
The error you're seeing is reported because data ->> 'identification' returns text, and the subsequent ->> is not defined for the text type.
Since version 9.3 Postgres has the #> and #>> operators. This operators allow the user to specify a path (using an array of text) inside jsonb column to get the value.
You could use this operator to achieve your goal in a simpler way.
CREATE INDEX ON mytable((data #>> '{identification, registration_number}'));

Select from JSONB field with WHERE clause

Just installed 9.4 and trying to use JSONB field type.
I've made a table with jsonb field and able to select from it:
select statistics->'statistics'->'all_trades'->'all'->'all_trades_perc_profit' as profitable_perc FROM trade_statistics
Works fine.
Now I want to filter results based on field value:
select statistics->'statistics'->'all_trades'->'all'->'all_trades_perc_profit' as profitable_perc FROM trade_statistics WHERE profitable_perc > 1
//There is no "profitable_perc" column
Does not work.
If I try to convert result to double, does not work either.
select cast(statistics->'statistics'->'all_trades'->'all'->'all_trades_perc_profit' as double precision) as profitable_perc FROM trade_statistics
//cant convert jsonb into double precision
How should I use select results in WHERE clause in case of jsonb?
Three corrections have to be made:
Wrap the the query in a subquery - you cannot reference the SELECT list aliases in WHERE clause
Use the ->> operator to get the value as text
Cast the text value as integer so you can make the comparison
SELECT *
FROM (
SELECT (statistics->'statistics'->'all_trades'->'all'->>'all_trades_perc_profit')::integer as profitable_perc
FROM trade_statistics
) sq1
WHERE profitable_perc > 1