json
in Postgres 9.3
Questo è difficile a pag 9.3, perché mancano funzionalità utili.
Metodo 1
Annulla l'annidamento in un LEFT JOIN LATERAL
(pulito e conforme agli standard), ritaglia le virgolette doppie da json
dopo aver trasmesso a text
. Vedi i link sotto.
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;
Sebbene funzioni, e non l'ho mai visto fallire, l'ordine degli elementi non annidati dipende da comportamenti non documentati. Vedi i link sotto!
Migliorata la conversione da json
a text
con l'espressione fornito da @pozs nel commento
. Ancora hacker, ma dovrebbe essere sicuro.
Metodo 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;
- Disannida in
SELECT
elenco (non standard). - Allega il numero di riga (
rn
) in parallelo (più affidabile). - Converti in
text
come sopra. - L'espressione
(last = name)
nelORDER BY
la clausola ordina i nomi corrispondenti per ultimi (ma prima di NULL). Quindi un nome corrispondente viene selezionato solo se non sono disponibili altri nomi. Ultimo link sotto.NelSELECT
elenco,NULLIF
sostituisce un nome corrispondente conNULL
, arrivando allo stesso risultato di cui sopra.
json
o jsonb
in Postgres 9.4
pg 9.4 fornisce tutti i miglioramenti necessari:
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;
Usa jsonb_array_elements_text()
per jsonb
. Tutto il resto uguale.
funzioni json / jsonb nel manuale
Risposte correlate con più spiegazioni:
- Come trasformare l'array json in un array postgres?
- PostgreSQL unnest() con numero elemento
- Indice per trovare un elemento in un array JSON
- Priorità basata sul tempo in Interrogazione record attiva
- Seleziona prima riga in ogni gruppo GROUP BY?