How to query a json column for empty objects?

落爺英雄遲暮 提交于 2019-11-26 07:38:56

问题


Looking to find all rows where a certain json column contains an empty object, {}. This is possible with JSON arrays, or if I am looking for a specific key in the object. But I just want to know if the object is empty. Can\'t seem to find an operator that will do this.

 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.

回答1:


There is no equality (or inequality) operator for the data type json as a whole, because equality is hard to establish. Consider jsonb in Postgres 9.4 or later, where this is possible. More details in this related answer on dba.SE (last chapter):

  • How to remove known elements from a JSON[] array in PostgreSQL?

SELECT DISTINCT json_column ... or ... GROUP BY json_column fail for the same reason (no equality operator).

Casting both sides of the expression to text allows = or <> operators, but that's not normally reliable as there are many possible text representations for the same json value.

However, for this particular case (empty object) it works just fine:

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



回答2:


As of PostgreSQL 9.5 this type of query with JSON data is not possible. On the other hand, I agree it would be very useful and created a request for it:

https://postgresql.uservoice.com/forums/21853-general/suggestions/12305481-check-if-json-is-empty

Feel free to vote it, and hopefully it will be implemented!




回答3:


In 9.3 it is possible to count the pairs in each object and filter the ones with none

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

or test the existence, probably faster for big objects

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

Both techniques will work flawlessly regardless of formating




回答4:


Empty JSON array [] could also be relevant.

Then this could work for both [] and {}:

select * from test where length(foo::text) > 2 ;


来源:https://stackoverflow.com/questions/24292575/how-to-query-a-json-column-for-empty-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!