json
v Postgres 9.3
To je na str. 9.3 těžké, protože chybí užitečná funkce.
Metoda 1
Zrušte vnoření v LEFT JOIN LATERAL
(čisté a v souladu se standardy), ořízněte dvojité uvozovky z json
po odeslání do text
. Viz odkazy níže.
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;
I když to funguje a nikdy jsem neviděl, že by to selhalo, pořadí nevnořených prvků závisí na nezdokumentovaném chování. Viz odkazy níže!
Vylepšena konverze z json
na text
s výrazem poskytl @pozs v komentáři
. Stále hackerské, ale mělo by to být bezpečné.
Metoda 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;
- Uvolněte umístění v
SELECT
seznam (nestandardní). - Připojte číslo řádku (
rn
) paralelně (spolehlivější). - Převést na
text
jako výše. - Výraz
(last = name)
vORDER BY
klauzule seřadí odpovídající jména jako poslední (ale před NULL). Odpovídající název je tedy vybrán pouze v případě, že není k dispozici žádné jiné jméno. Poslední odkaz níže.VSELECT
seznam,NULLIF
nahradí odpovídající názevNULL
, čímž se dosáhne stejného výsledku jako výše.
json
nebo jsonb
v Postgres 9.4
str. 9.4 dodává všechna nezbytná vylepšení:
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;
Použijte jsonb_array_elements_text()
pro jsonb
. Vše ostatní stejné.
funkce json / jsonb v příručce
Související odpovědi s podrobnějším vysvětlením:
- Jak změnit pole json na pole postgres?
- PostgreSQL unnest() s číslem prvku
- Index pro nalezení prvku v poli JSON
- časová priorita v Aktivní dotaz na záznam
- Vyberte nejdříve řádek v každé skupině GROUP BY?