2

I am (still) new to postgresql and jsonb. I am trying to select some records from a subquery and am stuck. My data column looks like this (jsonb):

{"people": [{"age": "50", "name": "Bob"}], "another_key": "no"}
{"people": [{"age": "73", "name": "Bob"}], "another_key": "yes"}

And here is my query. I want to select all names that are "Bob" whose age is greater than 30:

SELECT * FROM mytable
WHERE (SELECT (a->>'age')::float
       FROM (SELECT jsonb_array_elements(data->'people') as a
             FROM mytable) as b 
       WHERE a @> json_object(ARRAY['name', 'Bob'])::jsonb
      ) > 30;

I get the error:

more than one row returned by a subquery used as an expression

I don't quite understand. If I do some simple substitution (just for testing) I can do this:

SELECT * FROM mytable
WHERE  (50) > 30  -- 50 is the age of the youngest Bob

and that returns both rows.

4

3 に答える 3

1

サブクエリで:

SELECT (a->>'age')::float
FROM (SELECT jsonb_array_elements(data->'people') as a
      FROM mytable) as b
WHERE a @> json_object(ARRAY['name', 'Bob'])::jsonb

もう一度すべての行を選択しmytableました。サブクエリが複数の値を返すのはそのためです。

特定の条件を満たす要素を含むテーブルから行を選択する場合は、条件でそのテーブルから再選択しないでください。外側のクエリで既に選択した行を使用します。

SELECT * FROM mytable
WHERE exists(SELECT 1
    FROM (SELECT jsonb_array_elements(data->'people') as person) as x
    WHERE person @> '{"name": "Bob"}'
    AND (person->>'age')::float > 30)

私が知る限り、奇妙なダブル サブクエリ構文が必要です。data外側のクエリからのものであることに注意してください。

"people"条件を満たすフィールドからすべての JSON オブジェクトを選択したい場合は、"people"それらすべての要素を集約してフィルター処理するだけです。

SELECT person
FROM (SELECT jsonb_array_elements(data->'people') as person
      FROM mytable) as x
WHERE person @> '{"name": "Bob"}'
AND (person->>'age')::float > 30
于 2015-06-16T05:05:34.227 に答える