json
di Postgres 9.3
Ini sulit di hal 9.3, karena fungsi yang berguna tidak ada.
Metode 1
Hapus sarang dalam LEFT JOIN LATERAL
(bersih dan sesuai standar), potong tanda kutip ganda dari json
setelah casting ke text
. Lihat tautan di bawah.
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;
Meskipun ini berhasil, dan saya belum pernah melihatnya gagal, urutan elemen yang tidak bersarang bergantung pada perilaku yang tidak didokumentasikan. Lihat tautan di bawah!
Meningkatkan konversi dari json
ke text
dengan ekspresi disediakan oleh @pozs di komentar
. Masih retas, tapi harus aman.
Metode 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;
- Hapus sarang di
SELECT
daftar (tidak standar). - Lampirkan nomor baris (
rn
) secara paralel (lebih dapat diandalkan). - Konversikan ke
text
seperti di atas. - Ekspresi
(last = name)
diORDER BY
klausa mengurutkan nama yang cocok terakhir (tetapi sebelum NULL). Jadi nama yang cocok hanya dipilih jika tidak ada nama lain yang tersedia. Tautan terakhir di bawah. DiSELECT
daftar,NULLIF
mengganti nama yang cocok denganNULL
, sampai pada hasil yang sama seperti di atas.
json
atau jsonb
di Postgres 9.4
hal 9.4 mengirimkan semua peningkatan yang diperlukan:
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;
Gunakan jsonb_array_elements_text()
untuk jsonb
. Semuanya sama.
fungsi json / jsonb dalam manual
Jawaban terkait dengan penjelasan lebih lanjut:
- Bagaimana cara mengubah array json menjadi array postgres?
- PostgreSQL unnest() dengan nomor elemen
- Indeks untuk menemukan elemen dalam larik JSON
- Prioritas berbasis waktu di Kueri Rekaman Aktif
- Pilih dulu baris di setiap grup GROUP BY?