json
en Postgres 9.3
Esto es difícil en la página 9.3, porque falta una funcionalidad útil.
Método 1
Desanidar en un LEFT JOIN LATERAL
(limpio y conforme a los estándares), recorte las comillas dobles de json
después de enviar a text
. Ver enlaces a continuación.
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;
Si bien esto funciona, y nunca lo he visto fallar, el orden de los elementos no anidados depende del comportamiento no documentado. ¡Vea los enlaces a continuación!
Mejoró la conversión de json
a text
con la expresión proporcionado por @pozs en el comentario
. Sigue siendo hackish, pero debería 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;
- Anular el anidamiento en
SELECT
lista (no estándar). - Adjuntar número de fila (
rn
) en paralelo (más fiable). - Convertir a
text
como arriba. - La expresión
(last = name)
en elORDER BY
la cláusula ordena los nombres coincidentes en último lugar (pero antes de NULL). Por lo tanto, solo se selecciona un nombre coincidente si no hay otro nombre disponible. Último enlace a continuación. EnSELECT
lista,NULLIF
reemplaza un nombre coincidente conNULL
, llegando al mismo resultado que el anterior.
json
o jsonb
en Postgres 9.4
pg 9.4 incluye todas las mejoras necesarias:
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()
para jsonb
. Todo lo demás igual.
funciones json/jsonb en el manual
Respuestas relacionadas con más explicaciones:
- ¿Cómo convertir una matriz json en una matriz postgres?
- PostgreSQL unnest() con número de elemento
- Índice para encontrar un elemento en una matriz JSON
- Prioridad basada en tiempo en Consulta de registro activo
- Seleccionar primero fila en cada grupo GROUP BY?