json in Postgres 9.3
Dies ist in Seite 9.3 schwierig, da nützliche Funktionen fehlen.
Methode 1
Entschachteln Sie in einem LEFT JOIN LATERAL (sauber und standardkonform), doppelte Anführungszeichen von json entfernen nach dem Casting in text . Siehe Links unten.
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;
Obwohl dies funktioniert und ich noch nie gesehen habe, dass es fehlgeschlagen ist, hängt die Reihenfolge der nicht verschachtelten Elemente von undokumentiertem Verhalten ab. Siehe Links unten!
Konvertierung von json verbessert zu text mit dem Ausdruck bereitgestellt von @pozs im Kommentar
. Immer noch hackish, sollte aber sicher sein.
Methode 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;
- Entschachteln Sie im
SELECTListe (kein Standard). - Zeilennummer anhängen (
rn) parallel (zuverlässiger). - In
textumwandeln wie oben. - Der Ausdruck
(last = name)im FeldORDER BY-Klausel sortiert übereinstimmende Namen zuletzt (aber vor NULL). Ein passender Name wird also nur ausgewählt, wenn kein anderer Name verfügbar ist. Letzter Link unten. ImSELECTListe,NULLIFersetzt einen übereinstimmenden Namen durchNULL, und komme zum selben Ergebnis wie oben.
json oder jsonb in Postgres 9.4
pg 9.4 enthält alle notwendigen Verbesserungen:
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;
Verwenden Sie jsonb_array_elements_text() für jsonb . Alles andere gleich.
json / jsonb-Funktionen im Handbuch
Verwandte Antworten mit mehr Erklärung:
- Wie wandle ich ein JSON-Array in ein Postgres-Array um?
- PostgreSQL-unnest() mit Elementnummer
- Index zum Auffinden eines Elements in einem JSON-Array
- Zeitbasierte Priorität in Aktive Datensatzabfrage
- Zuerst auswählen Zeile in jeder GROUP BY-Gruppe?