json no Postgres 9.3
Isso é difícil na página 9.3, porque faltam funcionalidades úteis.
Método 1
Desaninhar em um
LEFT JOIN LATERAL (limpo e em conformidade com o padrão), corte aspas duplas de json após a conversão para text . Veja os links abaixo. 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;
Embora isso funcione, e eu nunca o vi falhar, a ordem dos elementos não aninhados depende do comportamento não documentado. Veja os links abaixo!
Melhorou a conversão de
json para text com a expressão fornecido por @pozs no comentário
. Ainda hackish, mas deve ser seguro. Método 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;
- Desaninhar no
SELECTlista (não padrão). - Anexar o número da linha (
rn) em paralelo (mais confiável). - Converter em
textcomo acima. - A expressão
(last = name)noORDER BYcláusula classifica os nomes correspondentes por último (mas antes de NULL). Portanto, um nome correspondente só é selecionado se nenhum outro nome estiver disponível. Último link abaixo. NoSELECTlista,NULLIFsubstitui um nome correspondente porNULL, chegando ao mesmo resultado acima.
SQL Fiddle.
json ou jsonb no Postgres 9.4
pg 9.4 envia todas as melhorias necessárias:
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;
Use
jsonb_array_elements_text() para jsonb . Todo o resto igual. funções json / jsonb no manual
Respostas relacionadas com mais explicações:
- Como transformar array json em array postgres?
- PostgreSQL unnest() com número de elemento
- Índice para encontrar um elemento em uma matriz JSON
- Prioridade baseada em tempo em Consulta de registro ativo
- Selecione primeiro linha em cada grupo GROUP BY?