Entrambe le risposte collegate contengono soluzioni, ma potrebbe essere utile avere una risposta omnibus.
Postgres è fortemente tipizzato. Le sue funzioni e gli operatori restituiscono tipi specifici.
->
restituisce jsonb. Confrontalo non con SQL null ma jsonb null
.
test=# select '{"i_am_null": null, "a_string": "null"}'::jsonb->'i_am_null' = 'null'::jsonb;
?column?
----------
t
(1 row)
test=# select '{"i_am_null": null, "a_string": "null"}'::jsonb->'a_string' = 'null'::jsonb;
?column?
----------
f
(1 row)
->>
restituisce il testo e convertirà jsonb null in SQL null
.
test=# select '{"i_am_null": null, "a_string": "null"}'::jsonb->>'i_am_null' is null;
?column?
----------
t
(1 row)
test=# select '{"i_am_null": null, "a_string": "null"}'::jsonb->>'a_string' is null;
?column?
----------
f
(1 row)
Nota che mentre jsonb null è solo un altro valore, SQL null è molto speciale. Null non è un valore, è la mancanza di un valore. Null equivale a niente, nemmeno null . Potrebbe sembrare che il cast di null su jsonb debba produrre jsonb null, ma lo standard SQL richiede che null esegua solo il cast su null altrimenti ciò significherebbe null è equivalente a qualcosa.
Questo è il motivo per cui jsonb null può essere convertito in null, ma null non viene convertito in jsonb null. null::jsonb
è nullo . Questo è scomodo, ma richiesto dallo standard SQL. È uno dei motivi per cui non è consigliabile eseguire il casting avanti e indietro tra jsonb e text.