【问题标题】:GROUP BY in Postgres - no equality for JSON data type?Postgres中的GROUP BY - JSON数据类型不相等?
【发布时间】:2015-08-11 17:20:44
【问题描述】:

我在匹配表中有以下数据:

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;

返回上面我想要的。谁有更好的解决方案?

【问题讨论】:

  • 尝试将team->'Name' 转换为text
  • 提供您的 Postgres 版本应该是显而易见的。对于最佳答案很重要。表定义也很有用。

标签: sql json postgresql greatest-n-per-group lateral


【解决方案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 和相等性

Postgres 中没有json 数据类型的相等运算符,但jsonb 有一个相等运算符(Postgres 9.4+):

【讨论】:

  • 只需要把(t.team->'Name')改成(t.team->>'Name'),json不相等。
  • @Watson:对,已修复。
  • 由于 jsonb 在 9.4+ 中具有相等运算符,因此在某些情况下,您可以将 json 列转换为 jsonb,使用 my_json_column::jsonb
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-28
  • 2021-09-09
  • 1970-01-01
  • 2011-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多