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
SELECTdaftar (tidak standar). - Lampirkan nomor baris (
rn) secara paralel (lebih dapat diandalkan). - Konversikan ke
textseperti di atas. - Ekspresi
(last = name)diORDER BYklausa 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. DiSELECTdaftar,NULLIFmengganti 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?