2014-06-18 14 views
29

Suchen nach allen Zeilen, in denen eine bestimmte JSON-Spalte ein leeres Objekt enthält, {}. Dies ist mit JSON-Arrays möglich, oder wenn ich nach einem bestimmten Schlüssel im Objekt suche. Aber ich möchte nur wissen, ob das Objekt leer ist. Ich kann keinen Operator finden, der das tut.Wie Abfrage einer JSON-Spalte für leere Objekte?

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. 

Antwort

55

Es gibt keine Gleichheit (oder Ungleichheit) Operator für den Datentyp json als Ganzes, weil Gleichheit schwer zu begründen ist. Sie werden Liebejsonb in Postgres 9.4, wo dies möglich ist. Mehr Details in diesem Stand der Antwort auf dba.SE (letzte Kapitel):

Casting beide Seiten des Ausdrucks text ermöglicht = oder <> Betreiber, aber das ist normalerweise nicht zuverlässig, gibt es viele mögliche Textdarstellungen für den gleichenjson Wert.

Für diesen speziellen Fall, aber es funktioniert einfach gut:

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

Frisch aus dem Ofen: http://www.postgresql.org/about/news/1557/ – opyate

+2

Wahrscheinlich offensichtlich, aber das funktioniert auch für leere Arrays ersetzen Sie einfach die {} mit [] – hobberwickey

+1

Wenn Sie suchen verschachtelte Strukturen, könnten Sie folgendes verwenden: 'Wählen Sie * aus test where foo - >> 'property' = '[]';' wobei die Struktur etwa so aussehen könnte: '{" property ": []," foo ":" bar "}' – Dynom

1

In 9.3 ist es möglich, die Paare in jedem Objekt zu zählen und die, die mit keinem

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 
----- 
{} 

oder Prüffilter die Existenz, wahrscheinlich schneller für große Objekte

Beide Techniken werden einwandfrei funktionieren rega rlless of formating

+0

Warum das 's' nach dem json_each Aufruf in diesen Beispielen? Welchen Zweck erfüllt es? – Stratus3D

+0

@ Stratus3D Es ist der obligatorische Alias ​​für eine Unterabfrage, in diesem Fall eine Funktion. –

Verwandte Themen