json
в Postgres 9.3
Това е трудно в стр. 9.3, защото липсва полезна функционалност.
Метод 1
Разместете в LEFT JOIN LATERAL
(изчистено и отговарящо на стандарта), изрежете двойните кавички от json
след прехвърляне към text
. Вижте връзките по-долу.
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;
Въпреки че това работи и никога не съм го виждал да се проваля, редът на невложените елементи зависи от недокументирано поведение. Вижте връзките по-долу!
Подобрено преобразуване от json
към text
с израза предоставено от @pozs в коментар
. Все още хакерски, но би трябвало да е безопасно.
Метод 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;
- Unnest в
SELECT
списък (нестандартен). - Прикачете номер на ред (
rn
) паралелно (по-надеждно). - Преобразуване в
text
като по-горе. - Изразът
(last = name)
вORDER BY
клаузата сортира съвпадащите имена последно (но преди NULL). Така че съответстващо име се избира само ако няма друго име. Последна връзка по-долу. ВSELECT
списък,NULLIF
замества съответстващо име сNULL
, достигайки до същия резултат като по-горе.
json
или jsonb
в Postgres 9.4
pg 9.4 предоставя всички необходими подобрения:
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;
Използвайте jsonb_array_elements_text()
за jsonb
. Всичко друго е същото.
json / jsonb функции в ръководството
Свързани отговори с повече обяснения:
- Как да превърна json масив в postgres масив?
- PostgreSQL unnest() с номер на елемент
- Индекс за намиране на елемент в JSON масив
- Приоритет, базиран на време в Заявка за активен запис
- Изберете първо ред във всяка група GROUP BY?