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

postgresqlテーブルからJSON配列要素を動的に選択する必要があります

    json Postgres9.3で

    9.3ページでは、便利な機能が不足しているため、これは困難です。

    方法1

    LEFT JOIN LATERALでネストを解除します (クリーンで標準に準拠)、jsonから二重引用符を削除します textにキャストした後 。以下のリンクを参照してください。

    SELECT DISTINCT ON (1)
           t.id, t.name, d.last
    FROM   tbl t
    LEFT   JOIN LATERAL (
      SELECT ('[' || d::text || ']')::json->>0 AS last
      FROM   json_array_elements(t.data) d
      ) d ON d.last <> t.name
    ORDER  BY 1, row_number() OVER () DESC;
    

    これは機能し、失敗するのを見たことがありませんが、ネストされていない要素の順序は、文書化されていない動作によって異なります。以下のリンクを参照してください!
    jsonからの変換を改善しました textへ 式コメントで@pozsによって提供されました 。まだハックですが、安全なはずです。

    方法2

    SELECT DISTINCT ON (1)
           id, name, NULLIF(last, name) AS last
    FROM (
       SELECT t.id, t.name
            ,('[' || json_array_elements(t.data)::text || ']')::json->>0 AS last
            , row_number() OVER () AS rn
       FROM   tbl t
       ) sub
    ORDER  BY 1, (last = name), rn DESC;
    
    • SELECTでネストを解除します リスト(非標準)。
    • 行番号を添付します(rn )並列(より信頼性が高い)。
    • textに変換 上記のように。
    • (last = name) ORDER BYで 句は、一致する名前を最後に(ただしNULLの前に)ソートします。したがって、一致する名前は、他の名前が使用できない場合にのみ選択されます。以下の最後のリンク。SELECT内 リスト、NULLIF 一致する名前をNULLに置き換えます 、上記と同じ結果に到達します。

    SQLフィドル。

    json またはjsonb Postgres9.4で

    9.4ページには必要なすべての改善が含まれています:

    SELECT DISTINCT ON (1)
           t.id, t.name, d.last
    FROM   tbl t
    LEFT   JOIN LATERAL json_array_elements_text(data) WITH ORDINALITY d(last, rn)
           ON d.last <> t.name
    ORDER  BY d.rn DESC;
    

    jsonb_array_elements_text()を使用します jsonbの場合 。他はすべて同じです。

    json/jsonb関数のマニュアル

    詳細な説明付きの関連回答:




    1. ORA-28040:一致する認証プロトコルの例外はありません

    2. jqueryでmysqlレコードを削除する方法

    3. 大きなSQLスクリプトを実行する(GOコマンドを使用)

    4. カスタムnextval関数内のmysqlbigint変数宣言のエラー