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
へ 式
方法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
に置き換えます 、上記と同じ結果に到達します。
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配列をpostgres配列に変換する方法
- 要素番号付きのPostgreSQLunnest()
- JSON配列内の要素を見つけるためのインデックス
- 時間ベースの優先度アクティブレコードクエリ
- 最初に選択各GROUPBYグループの行?