2016-01-25 21 views
6

jestem w stanie wybrać wartości nie zerowe z nieruchomości wewnątrz pola JSONB w PostgreSQL 9.5wartości wybrać, które nie tracą z pola JSONB w PostgreSQL

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

Próbowałem też za pomocą NOTNULL.

Otrzymuję błąd 42883 po uruchomieniu któregokolwiek z nich. "BŁĄD: Operator nie istnieje JSONB - >> wartość logiczna Wskazówka: Żaden operator nie pasuje do podanej nazwy i typu argumentu. Może być konieczne dodanie wyraźnych rzutów typów."

+0

Dzięki, kopiowanie/wklejanie kończy się niepowodzeniem. – sheldonkreger

+2

Czy na pewno nie używasz 9.4? W 9.4 operator '- >>' ma niższy priorytet niż 'IS [NOT] NULL' (więc twoje zapytanie jest przetwarzane jako' data - >> ('właściwość' NIE JEST NULL ")). Nie mam teraz instancji 9.5, aby przetestować, ale wydaje się (z odpowiedzi @Patrick'a), że może to być poprawa wprowadzona w 9.5. W 9.4 najprostszym rozwiązaniem jest użycie nawiasu: '(data - >> 'właściwość') NIE JEST NIŻEJ. – pozs

+1

Zmiana rzeczywiście się wydarzyła: [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) ('->' i '- >>' znajduje się wewnątrz * (dowolnego innego) * operatora). – pozs

Odpowiedz

7

szybko przetestowaniu pytanie i znaleźć bez problemu:

[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)

pamiętać, że w jsonb wartość NULL powinna być określona precyzyjnie więc na wejściu (jak w powyższym przykładzie), a nie w jakiejś wersji cytowanej. Jeśli wartość nie jest równa NULL, ale pusty ciąg lub coś w rodzaju '<null>' (ciąg znaków), należy dostosować test, aby to sprawdzić: WHERE data->>'property' = ''. W takim przypadku można rozważyć użycie jsonb_set(), aby ustawić takie wartości na prawdziwe json null.

Nawiasem mówiąc, można także zrobić:

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

tj testować wartość jsonb dla NULL raczej niż jego obsady do text. Bardziej wydajny, na pewno na większych stołach. To oczywiście działa tylko na prawdziwe s. null.

+1

Niestety nie mogę opublikować JSON tutaj, ale mogę zrobić kilka komentarzy. 1. Inne zapytania dotyczące JSONB działają dobrze. 2. Wygląda na to, że większość danych w tym konkretnym atrybucie JSON jest zdefiniowana jako sheldonkreger

+0

Nie sądzę, że moja właściwość JSON jest ustawiona na 'null' w sposób opublikowany. Czy istnieje sposób sprawdzenia pustego ciągu? – sheldonkreger

+1

Zobacz zaktualizowaną odpowiedź – Patrick