Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

I am unable to select non-null values from a property inside a JSONB field in Postgres 9.5

SELECT data->>'property' FROM mytable WHERE data->>'property' IS NOT NULL;

I also tried using NOTNULL.

I receive error 42883 when I run either of these. "ERROR: Operator does not exist. JSONB->>boolean Hint: No operator matches the given name and argument type(s). You might need to add explicit type casts."

share|improve this question
    
Thanks, copy/paste fail. – sheldonkreger Jan 25 at 5:20
    
Are you sure you don't use 9.4? In 9.4 the ->> operator has lower precedence than the IS [NOT] NULL (so your query is parsed as data ->> ('property' IS NOT NULL)). I have no 9.5 instance right now to test, but it seems (from @Patrick 's answer) that this might be an improvement introduced in 9.5. In 9.4 the simplest workaround is to use parenthesis: (data->>'property') IS NOT NULL. – pozs Jan 25 at 16:27
    
Change is indeed happened: 9.4 vs. 9.5 (-> and ->> is within the (any other) operator). – pozs Jan 25 at 16:34

I quickly tested your question and found no problem:

patrick@brick:~$ psql -d test
psql (9.5.0)
Type "help" for help.

test=# CREATE TABLE mytable (id serial PRIMARY KEY, data jsonb);
CREATE TABLE
test=# INSERT INTO mytable (data) VALUES
('{"ip": "192.168.0.1", "property": "router"}'),
('{"ip": "127.0.0.1", "property": "localhost"}'),
('{"ip": "192.168.0.15", "property": null}');
INSERT 0 3
test=# SELECT * FROM mytable;
 id |                     data
----+----------------------------------------------
  1 | {"ip": "192.168.0.1", "property": "router"}
  2 | {"ip": "127.0.0.1", "property": "localhost"}
  3 | {"ip": "192.168.0.15", "property": null}
(3 rows)

test=# SELECT data->>'property' FROM mytable WHERE data->>'property' IS NOT NULL;
 ?column?
-----------
 router
 localhost
(2 rows)

Note that in jsonb a NULL value should be specified precisely so on input (as in the sample above), not in some quoted version. If the value is not NULL but an empty string or something like '<null>' (a string) then you should adapt your test to look for that: WHERE data->>'property' = ''. If this is the case you could consider using jsonb_set() to set such values to a true json null.

Incidentally, you could also do:

SELECT data->>'property' FROM mytable WHERE data->'property' IS NOT NULL;

i.e. test the jsonb value for NULL rather than its cast to text. More efficient, certainly on larger tables. This obviously only works on true nulls.

share|improve this answer
1  
Unfortunately I can't post the JSON here but I can make a few comments. 1. Other queries on the JSONB work well. 2. It looks like most the data in this particular attribute of the JSON is defined as <null> – sheldonkreger Jan 25 at 5:34
    
I don't think my JSON property is being set to null in the way you posted. Is there a way to check for an empty string? – sheldonkreger Jan 25 at 5:36
    
See updated answer – Patrick Jan 25 at 5:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.