web-dev-qa-db-ja.com

PostgresのGROUP BY-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"}]}"

[〜#〜] edit [〜#〜]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;

上記で欲しかったものを返します。誰かがより良い解決策を持っていますか?

18
janderson

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+)には等価演算子があります。

11