PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

È necessario selezionare dinamicamente un elemento dell'array JSON da una tabella postgresql

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) nel ORDER 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.Nel SELECT elenco, NULLIF sostituisce un nome corrispondente con NULL , arrivando allo stesso risultato di cui sopra.

SQL Fiddle.

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: