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
SELECTlista (no estándar). - Adjuntar número de fila (
rn) en paralelo (más fiable). - Convertir a
textcomo arriba. - La expresión
(last = name)en elORDER BYla 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. EnSELECTlista,NULLIFreemplaza 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?