1

私は次の(簡略化された)構造を持っています:

 id |            j            
----+-------------------------
  1 | {"price": [1, 2, 3, 4]}
  2 | {"price": [4, 5, 6, 7]}
  3 | {"something": "else"}

理想的には、次のようなクエリを実行したいと思います。

select id from testjson where any(j->'price') between 5 and 8;

私は回避策を思い付くことができました:

select id from testjson where any_between(j->'price',5,8);

以前に以下を定義しました。

CREATE OR REPLACE FUNCTION jsonb_array_bigint(_j jsonb) RETURNS bigint[] AS
$$
SELECT array_agg(elem::text::bigint) FROM jsonb_array_elements(_j) AS elem
$$
LANGUAGE sql IMMUTABLE;

CREATE OR REPLACE FUNCTION any_between(_j jsonb,lower bigint, higher bigint) RETURNS boolean AS
$$
select (lower <= any(arr) and higher >= any(arr)) from jsonb_array_bigint(_j) as arr  
$$
LANGUAGE sql IMMUTABLE;

これは機能しますが、少しハックであり、あまり効率的ではありません。より良い方法はありますか?

4

1 に答える 1

1

json_array_elements配列を行に拡張するために使用できます。

select  distinct id
from    Table1
cross join    
        json_array_elements((j->'price')::json)
where   value::text::int between 5 and 8

SQL Fiddle の例。 この例は、 SQL jsonFiddlejsonbがまだ 9.4 をサポートしていないためです。

于 2015-05-27T14:31:24.297 に答える