2014-06-18 13 views
29

Szukając wszystkich wierszy, w których pewna kolumna json zawiera pusty obiekt, {}. Jest to możliwe z tablicami JSON lub gdy szukam określonego klucza w obiekcie. Ale chcę tylko wiedzieć, czy obiekt jest pusty. Nie można znaleźć operatora, który to zrobi.Jak wykonać zapytanie o kolumnę json dla pustych obiektów?

dev=# \d test 
    Table "public.test" 
    Column | Type | Modifiers 
--------+------+----------- 
    foo | json | 

dev=# select * from test; 
    foo 
--------- 
    {"a":1} 
    {"b":1} 
    {} 
(3 rows) 

dev=# select * from test where foo != '{}'; 
ERROR: operator does not exist: json <> unknown 
LINE 1: select * from test where foo != '{}'; 
            ^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. 
dev=# select * from test where foo != to_json('{}'::text); 
ERROR: operator does not exist: json <> json 
LINE 1: select * from test where foo != to_json('{}'::text); 
            ^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. 
dwv=# select * from test where foo != '{}'::json; 
ERROR: operator does not exist: json <> json 
LINE 1: select * from test where foo != '{}'::json; 
            ^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. 

Odpowiedz

55

Jest ma równości (albo nierówności) operatora do typu danych json jako całości, ponieważ równość jest trudne do ustalenia. Będziesz miłośćjsonb w Postgres 9.4, gdzie jest to możliwe. Więcej szczegółów w tym powiązanej odpowiedź na dba.SE (ostatni rozdział):

Casting obu stronach wypowiedzi text pozwala = lub <> operatorów, ale nie jest to zwykle niezawodny, istnieją wiele możliwych reprezentacji tekstu dla wartości o tej samej wartości.

W tym konkretnym przypadku, jednak, to działa dobrze:

select * from test where foo::text <> '{}'::text; 
+0

Świeżo z pieca: http://www.postgresql.org/about/news/1557/ – opyate

+2

Prawdopodobnie jest to oczywiste, ale działa to również w przypadku pustych tablic, wystarczy wymienić {} na [] – hobberwickey

+1

Jeśli szukasz zagnieżdżone struktury, może być coś, co możesz użyć: 'wybierz * z testu gdzie foo - >> 'właściwość' = '[]';' gdzie struktura może wyglądać następująco: '{" własność ": []," foo ":" bar "}' – Dynom

1

W 9.3 możliwe jest policzyć par w każdym obiekcie i odfiltrować te z żadnym

create table test (foo json); 
insert into test (foo) values 
('{"a":1, "c":2}'), ('{"b":1}'), ('{}'); 

select * 
from test 
where (select count(*) from json_each(foo) s) = 0; 
foo 
----- 
{} 

lub test istnienie, prawdopodobnie szybsze dla dużych obiektów

select * 
from test 
where not exists (select 1 from json_each(foo) s); 

Obie techniki będą działały bez problemu rega rdless formowania

+0

Dlaczego 's' po wywołaniu json_each w tych przykładach? Do czego to służy? – Stratus3D

+0

@ Stratus3D Jest to obowiązkowy alias dla podzapytania, w tym przypadku funkcja. –

Powiązane problemy