2017-02-08 12 views
0

jsonbオブジェクトフィールドの比較を含む特定の条件に一致するテーブルから行を選択する必要があります。jsonb配列内の特定のオブジェクトをターゲットにする

以下の例では、値が配列のオブジェクトで指定されている最小値/最大値の範囲内の行のみを取得したいとします。array_of_objectsのオブジェクトが含まれている場合は、最小/最大比較を使用)value、私はその行が必要です。与えられた例のために、私は値822と行のみを取得したいので、

CREATE TABLE test_table (
    id serial, 
    value int, 
    array_of_objects jsonb[] 
); 

INSERT INTO 
    test_table (value, array_of_objects) 
VALUES 
    (8, ARRAY ['{"min":5,"max":15}', '{"min":4,"max":18}']::jsonb[]), 
    (6, ARRAY ['{"min":12,"max":18}', '{"min":19,"max":22}']::jsonb[]), 
    (22, ARRAY ['{"min":16,"max":18}', '{"min":34,"max":47}']::jsonb[]); 

+0

MX:18 22少ないし、とてもここにも、なぜ22?配列のすべての要素に対して適用される条件がありますか? –

+0

私の答えを見てください - "value"列の配列のすべての要素にmin

答えて

2

あなたは、元の列をしたい場合:

t=# with a as (select unnest(array_of_objects) j,* from test_table) 
select distinct id,value, array_of_objects 
from a 
where (j->>'min')::int < value and (j->>'max')::int > value; 
id | value |      array_of_objects 
----+-------+----------------------------------------------------------- 
    1 |  8 | {"{\"max\": 15, \"min\": 5}","{\"max\": 18, \"min\": 4}"} 
(1 row) 

、ここでは、なぜ値22は(array_of_objects [1]それに取得していない "説明" である - >>最大22そして小さい:

Time: 0.441 ms 
t=# with a as (select unnest(array_of_objects) j,* from test_table) 
select distinct id,value,j 
from a 
where (j->>'min')::int < value and (j->>'max')::int > value; 
id | value |   j 
----+-------+----------------------- 
    1 |  8 | {"max": 18, "min": 4} 
    1 |  8 | {"max": 15, "min": 5} 
(2 rows) 

Time: 0.390 ms 
+0

ありがとうございます!あなたが単一の行を返すという事実は理にかなっています。私は質問を書き留める際に間違いを犯しました。 – gmile

+0

jsonbネストした配列をこのように検索するより効率的な方法があると思いますか?それはunexest経由で行を複製するのが少し遅いかもしれませんか? – gmile

+0

あなたは比較のために配列要素を入れ子にしなければならないと思います。一つずつ –

0

JSON関連の巨大な塊を実装するPostgreSQLのCommitfestでPRがありますいつかPostgreSQLの10

unnestを使用して回避することが可能になります最新SQL 2016規格の一部として標準化機能、:

ここでは例です:

CREATE TABLE my_table (
    title VARCHAR, 
    number INTEGER, 
    my_array JSONB 
); 

INSERT INTO my_table (title, number, my_array) VALUES 
    ('not expected', 6, '[{"min": 1, "max": 5}, {"min": 7, "max": 10}]'::JSONB), 
    ('expected', 7, '[{"min": 1, "max": 5}, {"min": 7, "max": 10}]'::JSONB); 

SELECT * 
    FROM my_table 
WHERE JSON_EXISTS(my_array, '$[*] ? (@.min < $x && $x <= @.max)' PASSING number AS x); 
関連する問題