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
SELECTseznam (nestandardní). - Připojte číslo řádku (
rn) paralelně (spolehlivější). - Převést na
textjako výše. - Výraz
(last = name)vORDER BYklauzule 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.VSELECTseznam,NULLIFnahradí 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?