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
SELECT
Liste (kein Standard). - Zeilennummer anhängen (
rn
) parallel (zuverlässiger). - In
text
umwandeln 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. ImSELECT
Liste,NULLIF
ersetzt 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?