I try this:
select * from "User" where "partnerData" -> 'name' != NULL
partnerData is a JSONB. I would see those rows, does not have the name field in JSON.
You can't use <> (or != or any other operator) to check for NULL values, you need to use IS NULL. Using -> also returns a jsonb value which might be the literal null not the SQL NULL value. So you should use ->> to return a text value (which would then be a SQL NULL)
select *
from "User"
where "partnerData" ->> 'name' IS NULL
Note that this doesn't distinguish between a JSON value that contains the key name but with a value of NULL and a JSON value that does not contain the key at all.
If you only want to check if the key exists (regardless of the value - even if it's a JSON null), use the ? operator.
where "partnerData" ? 'name'
Related
SELECT * FROM Entity e WHERE e.Status <> ANY(ARRAY[1,2,3]);
Here Status is a nullable integer column. Using the above query i am unable to fetch the records whose status value is NULL.
SELECT * FROM Entity e WHERE (e.Status is NULL OR e.Status = 4);
This query does the trick. Could someone explain me why the first query was not working as expected.
NULL kinda means "unknown", so the expressions
NULL = NULL
and
NULL != NULL
are neither true nor false, they're NULL. Because it is not known whether an "unknown" value is equal or unequal to another "unknown" value.
Since <> ANY uses an equality test, if the value searched in the array is NULL, then the result will be NULL.
So your second query is correct.
It is spelled out in the docs Array ANY:
If the array expression yields a null array, the result of ANY will be null. If the left-hand expression yields null, the result of ANY is ordinarily null (though a non-strict comparison operator could possibly yield a different result). Also, if the right-hand array contains any null elements and no true comparison result is obtained, the result of ANY will be null, not false (again, assuming a strict comparison operator). This is in accordance with SQL's normal rules for Boolean combinations of null values.
FYI:
e.Status is NULL OR e.Status = 4
can be shortened to:
e_status IS NOT DISTINCT FROM 4
per Comparison operators.
I have a field payload saved in a postgresql table which is json type. This type has a nested field subcategory which is string. Below is the output of this value:
=> select payload->'subcategory' from "Merchant";
?column?
-------------------------------
"Food"
null
"AUTOMOTIVE"
null
"MEDICAL"
null
null
"CLUB"
"Petrol Stations"
However, I can't put this field in the where clause. Below query returns 0 rows. But from above output it shows there are rows whose value is CLUB. What is the right way to use json field in where clause?
=> select count(*) from "Merchant" where ("payload"->'subcategory')::text = 'CLUB';
count
-------
0
Figured out what's wrong, I need to use ->> in the where like "payload"->'subcategory'.
that because ->> converts it to text while -> makes it as JSONB
An alternative solution is to use the JSON contains operator #>:
select count(*)
from "Merchant"
where payload #> '{"subcategory": "CLUB")';
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
I'm trying to update a bunch of jsonb values to null. Here's an example of what i'm trying to do and i'm getting the error below.
How can I set first-name to null in this case?
UPDATE users
SET
fields = fields || '{"first-name": NULL}'
WHERE user_id = 1;
ERROR: invalid input syntax for type json
LINE 3: fields = fields || '{"first-name": NULL}'
^
DETAIL: Token "NULL" is invalid.
CONTEXT: JSON data, line 1: {"first-name": NULL...
Use jsonb_set:
UPDATE users
SET
fields = jsonb_set(fields, '{first-name}', 'null')
WHERE user_id = 1;
If you want the null value inside the JSONB, then it must be a JSON null value, not an SQL NULL value. JSON null must be spelled in lower case.
I have a table Image
id | path | additional | item_id
1 /url/.. {"sm":"/url2/", "md": "/url3/"} 1
additional is an jsonb that can be Null, empty {}, or with values
I want to check in jsonb if a key like sm exist . If the key exist return the value if not return the path.
My starting idea is to use CASE but I have issue checking and retrieving the value from array
Use coalesce():
select id,
coalesce(additional ->> 'sm', path) as path
from image;
The operator ->> will return null if the key does not exist.