2016-01-25 15 views
6

non sono in grado di selezionare i valori non nulli da una struttura all'interno di un campo JSONB di PostgreSQL 9,5selezionare i valori che non sono nulle dal campo JSONB di PostgreSQL

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

Ho anche provato ad utilizzare notnull.

Ricevo l'errore 42883 quando eseguo uno di questi. "ERRORE: l'operatore non esiste JSONB - >> booleano Suggerimento: nessun operatore corrisponde al nome e ai tipi di argomento indicati. Potrebbe essere necessario aggiungere cast di tipo esplicito."

+0

Grazie, copia/incolla fallita. – sheldonkreger

+2

Sei sicuro di non usare 9.4? Nel 9.4 l'operatore '- >>' ha precedenza inferiore rispetto a 'IS [NOT] NULL' (quindi la tua query viene analizzata come 'data - >> (' property 'IS NOT NULL')). Non ho ora istanza 9.5 da testare, ma sembra (dalla risposta di @Patrick) che questo potrebbe essere un miglioramento introdotto in 9.5. In 9.4 la soluzione più semplice è usare le parentesi: '(data - >> 'property') IS NOT NULL'. – pozs

+1

Il cambiamento è effettivamente avvenuto: [9.4] (http://www.postgresql.org/docs/9.4/static/sql-syntax-lexical.html#SQL-PRECEDENCE-TABLE) vs. [9.5] (http: // www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-PRECEDENCE-TABLE) ('->' e '- >>' si trova all'interno dell'operatore * (qualsiasi altro) *). – pozs

risposta

7

Ho provato subito la tua domanda e hanno trovato nessun problema:

[email protected]:~$ 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)

Si noti che in jsonb un valore NULL dovrebbe essere specificato con precisione così via di ingresso (come nell'esempio sopra), non in qualche versione citata. Se il valore non è NULL ma una stringa vuota o qualcosa di simile a '<null>' (una stringa), allora dovresti adattare il test per cercare che: WHERE data->>'property' = ''. Se questo è il caso, potresti prendere in considerazione l'utilizzo di jsonb_set() per impostare tali valori su un vero jeff null.

Per inciso, si potrebbe anche fare:

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

cioè testare il valore jsonb per NULL piuttosto che il suo cast di text. Più efficiente, certamente su tavoli più grandi. Questo ovviamente funziona solo su true null s.

+1

Purtroppo non posso pubblicare il JSON qui ma posso fare alcuni commenti. 1. Altre query sul JSONB funzionano bene. 2. Sembra che la maggior parte dei dati in questo particolare attributo del JSON sia definito come sheldonkreger

+0

Non penso che la mia proprietà JSON sia impostata su 'null' nel modo in cui hai postato. C'è un modo per controllare una stringa vuota? – sheldonkreger

+1

Vedi risposta aggiornata – Patrick