sql - GROUP BY en Postgres: ¿no hay igualdad para el tipo de datos JSON?
postgresql greatest-n-per-group (1)
Tengo los siguientes datos en una tabla de coincidencias:
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]}
Quiero seleccionar cada último equipo distinto en la tabla por su nombre. Es decir, quiero una consulta que devolverá:
6;{"Name":"TeamA","Players":[{"Name":"CCC"},{"Name":"BBB"}
6;{"Name":"TeamB","Players":[{"Name":"AAA"},{"Name":"DDD"}
Así que cada equipo de la última vez que ese equipo aparece en la tabla.
He estado usando lo siguiente (desde 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'';
Pero esto vuelve:
ERROR: could not identify an equality operator for type json SQL state: 42883 Character: 1680
Entiendo que Postgres no tiene igualdad para JSON . Solo necesito igualdad para el nombre del equipo (una cadena), los jugadores de ese equipo no necesitan ser comparados.
¿Alguien puede sugerir una forma alternativa de hacer esto?
Para referencia:
SELECT id, json_array_elements(match->''Teams'') AS team FROM matches
devoluciones:
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"}]}"
EDITAR : Puse el text
y siguiendo esta pregunta , usé DISTINCT ON
lugar de GROUP BY
. Aquí está mi consulta completa:
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;
Devuelve lo que quería arriba. ¿Alguien tiene una solución mejor?
Más corto, más rápido y más elegante con una combinación 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"
Si solo quieres equipos distintos, el ORDER BY
puede ir. Relacionado:
JSON y la igualdad
No hay un operador de igualdad para el tipo de datos json
en Postgres, pero hay uno para jsonb
(Postgres 9.4+):