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+):