GROUP BY в Postgres - нет равенства для типа данных JSON?

У меня есть следующие данные в таблице соответствий:

5;{"Id":1,"Teams":[{"Name":"TeamA","Players":[{"Name":"AAA"},{"Name":"BBB"}]},{"Name":"TeamB","Players":[{"Name":"CCC"},{"Name":"DDD"}]}],"TeamRank":[1,2]}
6;{"Id":2,"Teams":[{"Name":"TeamA","Players":[{"Name":"CCC"},{"Name":"BBB"}]},{"Name":"TeamB","Players":[{"Name":"AAA"},{"Name":"DDD"}]}],"TeamRank":[1,2]}

Я хочу выбрать каждую последнюю команду в таблице по их названию. т.е. я хочу запрос, который будет возвращать:

6;{"Name":"TeamA","Players":[{"Name":"CCC"},{"Name":"BBB"}
6;{"Name":"TeamB","Players":[{"Name":"AAA"},{"Name":"DDD"}

Таким образом, каждая команда с прошлого раза, эта команда появляется в таблице.
Я использовал следующее ( отсюда):

WITH t AS (SELECT id, json_array_elements(match->'Teams') AS team FROM matches)
SELECT MAX(id) AS max_id, team FROM t GROUP BY team->'Name';

Но это возвращает:

ERROR: could not identify an equality operator for type json
SQL state: 42883
Character: 1680

Я понимаю, что у Postgres нет равенства для JSON. Мне нужно только равенство для названия команды (строка), игроков в этой команде не нужно сравнивать.

Кто-нибудь может предложить альтернативный способ сделать это?
Для справки:

SELECT id, json_array_elements(match->'Teams') AS team FROM matches

возвращает:

5;"{"Name":"TeamA","Players":[{"Name":"AAA"},{"Name":"BBB"}]}"
5;"{"Name":"TeamB","Players":[{"Name":"CCC"},{"Name":"DDD"}]}"
6;"{"Name":"TeamA","Players":[{"Name":"CCC"},{"Name":"BBB"}]}"
6;"{"Name":"TeamB","Players":[{"Name":"AAA"},{"Name":"DDD"}]}"

РЕДАКТИРОВАТЬ: я бросил в text и после этого вопроса я использовал DISTINCT ON вместо GROUP BY, Вот мой полный запрос:

WITH t AS (SELECT id, json_array_elements(match->'Teams') AS team
           FROM matches ORDER BY id DESC)
SELECT DISTINCT ON (team->>'Name') id, team FROM t;

Возвращает то, что я хотел выше. У кого-нибудь есть лучшее решение?

1 ответ

Решение

Короче, быстрее и элегантнее с LATERAL присоединиться:

SELECT DISTINCT ON (t.team->>'Name') t.team
FROM   matches m, json_array_elements(m.match->'Teams') t(team);
ORDER  BY t.team->>'Name', m.id DESC;  -- to get the "last"

Если вы просто хотите отдельных команд, ORDER BY можешь идти. Связанные с:

JSON и равенство

Там нет оператора равенства для json тип данных в Postgres, но есть один для jsonb (Postgres 9.4+):

Другие вопросы по тегам