sql >> データベース >  >> RDS >> PostgreSQL

IN演算子を使用してjsonb配列をクエリする方法

    簡単な答え

    関数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)
    

    関数の場合、これは不可能です。インデックスでサポートされるクエリは、関数を使用するクエリよりも最大で数十倍高速になる可能性があります。




    1. SequelProを使用してデータベースに接続する方法

    2. GRANT USAGE ON SCHEMAは正確に何をしますか?

    3. PrometheusとClusterControlを使用してProxySQLを監視する方法

    4. PostgreSQLの接続管理:ガイド