簡単な答え
関数jsonb_array_elements()
を使用できます 横方向の結合で、その結果のvalue
を使用します WHERE
の複雑な式で 条項:
SELECT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('b', 'd')
AND value->>'label1' IN ('2', '3')
個別
単一行の配列の複数の要素でフィルター条件が満たされた場合、クエリは重複した行を返すことがあります。例:
SELECT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
id | test_content
--------------------------------------+----------------------------------------------------------------
aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | [{"label": "a", "label1": "1"}, {"label": "b", "label1": "2"}]
aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | [{"label": "a", "label1": "1"}, {"label": "b", "label1": "2"}]
(2 rows)
したがって、DISTINCT
を使用するのが妥当な場合があります SELECT
で リスト:
SELECT DISTINCT t.*
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
またはEXISTS
WHERE
で 句、これは少し速いかもしれません:
SELECT t.*
FROM test t
WHERE EXISTS (
SELECT
FROM jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
)
この情報が必要な場合は、一致する配列要素を選択することもできます。
SELECT id, value
FROM test t
CROSS JOIN jsonb_array_elements(test_content)
WHERE value->>'label' IN ('a', 'b')
id | value
--------------------------------------+-------------------------------
aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | {"label": "a", "label1": "1"}
aa82a8b8-33ef-4937-bd8c-8a4b40960f18 | {"label": "b", "label1": "2"}
(2 rows)
パフォーマンス
jsonb_array_elements()
機能は高価です。大きなテーブルの場合、サーバーの負荷が高く、クエリの実行時間が長いため、関数の使用に問題がある可能性があります。
GINインデックスは、@>
を使用したクエリに使用できます。 演算子:
CREATE INDEX ON test USING GIN (test_content)
関数の場合、これは不可能です。インデックスでサポートされるクエリは、関数を使用するクエリよりも最大で数十倍高速になる可能性があります。