Postgres 中的 GROUP BY - JSON 数据类型不相等?
GROUP BY in Postgres - no equality for JSON data type?
我在比赛中有以下数据 table:
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]}
我想 select table 中每个最后一个不同的团队的名字。即我想要一个 return:
的查询
6;{"Name":"TeamA","Players":[{"Name":"CCC"},{"Name":"BBB"}
6;{"Name":"TeamB","Players":[{"Name":"AAA"},{"Name":"DDD"}
因此上次该团队出现在 table 中的每个团队。
我一直在使用以下内容(来自 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';
但是这个 returns:
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
returns:
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;
Returns我上面想要的。有人有更好的解决方案吗?
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
可以。相关:
- Query for element of array in JSON column
- Query for array elements inside JSON type
JSON 和相等
Postgres 中 json
数据类型没有相等运算符,但 jsonb
(Postgres 9.4+) 有一个:
- How to query a json column for empty objects?
我在比赛中有以下数据 table:
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]}
我想 select table 中每个最后一个不同的团队的名字。即我想要一个 return:
的查询6;{"Name":"TeamA","Players":[{"Name":"CCC"},{"Name":"BBB"}
6;{"Name":"TeamB","Players":[{"Name":"AAA"},{"Name":"DDD"}
因此上次该团队出现在 table 中的每个团队。
我一直在使用以下内容(来自 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';
但是这个 returns:
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
returns:
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;
Returns我上面想要的。有人有更好的解决方案吗?
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
可以。相关:
- Query for element of array in JSON column
- Query for array elements inside JSON type
JSON 和相等
Postgres 中 json
数据类型没有相等运算符,但 jsonb
(Postgres 9.4+) 有一个:
- How to query a json column for empty objects?