我在匹配表中有以下数据:
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"}
所以每个团队从上次那个团队出现在表中 我一直在使用以下(来自here):
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 doesn't have equality for 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
并跟随this question,我使用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;
返回上面我想要的内容。有没有人有更好的解决方案?
答案 0 :(得分:7)
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
就可以了。相关:
Postgres中的json
数据类型没有相等运算符,但jsonb
有一个(Postgres 9.4 +):