Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgres json_object. Add json field only if value is not null

Im using jsob_build_object function to generate json from data in my table.

select json_build_object('name', p.name, 'birthday', p.birthday)
FROM Person p limit 2

The result is:

{"name":"John", "birthday", "2000-01-01"}
{"name":"George", "birthday", "null"}

Now as you can see in second row birthday is null. In that case I would like that JSON field (birthday) to not be present there so the result would be:

{"name":"John", "birthday", "2000-01-01"}
{"name":"George"}

Is it possible?

like image 824
Witos Avatar asked Jan 31 '18 09:01

Witos


People also ask

Can JSON be null Postgres?

Returns the type of the outermost JSON value as a text string. Possible types are object, array, string, number, boolean, and null.

Can Jsonb be null?

Null is entered into the database when the value passed into JSONB. valueOf is null. The behavior is also a bit confusing since JSONB is just a simple wrapper so one cannot see why would it not handle null well.

What is difference between JSON and Jsonb?

The json data type stores an exact copy of the input text, which processing functions must reparse on each execution; while jsonb data is stored in a decomposed binary format that makes it slightly slower to input due to added conversion overhead, but significantly faster to process, since no reparsing is needed.

What is -> in Postgres?

Postgres offers 2 operators to get a JSON member: the arrow operator: -> returns type JSON or JSONB. the double arrow operator: ->> returns type text.


1 Answers

Use json_strip_nulls()

select json_strip_nulls(json_build_object('name', p.name, 'birthday', p.birthday))
FROM person p 
limit 2;

Edit 1 (after question has been extended)

If you want to do that conditionally, you can do that with jsonb (because it supports the || operator)

select jsonb_build_object('name', p.name) || jsonb_strip_nulls(jsonb_build_object('birthday', p.birthday))
from person p;

Edit 2 (after Postgres version has been disclosed)

If you are limited to an old version of Postgres you need to use a conditional expression where you only concatenate the JSON object if the column is not null:

select jsonb_build_object('name', p.name) 
       || case 
             when birthday is null then '{}'::jsonb 
             else jsonb_build_object('birthday', p.birthday) 
          end
from person p;
like image 194
a_horse_with_no_name Avatar answered Nov 09 '22 08:11

a_horse_with_no_name