Desafortunadamente, no hay ninguna disposición en la sintaxis SQL para decir "todas las columnas excepto esta columna" . Puede lograr su objetivo deletreando la lista restante de columnas en una expresión de tipo fila :
SELECT a.id, a.name
, json_agg((b.col1, b.col2, b.col3)) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
Esa es la abreviatura de la forma más explícita: . ROW
(b.col1, b.col2, b.col3)
Sin embargo, los nombres de las columnas no se conservan en las expresiones de tipo fila. Obtiene nombres de clave genéricos en el objeto JSON de esta manera. Veo 3 opciones para preservar los nombres de columna originales:
1. Transmitir al tipo registrado
Transmitir a un tipo de fila conocido (registrado). Se registra un tipo para cada tabla o vista existente o con una CREATE TYPE
declaración explícita . Puede usar una tabla temporal para una solución ad-hoc (dura toda la sesión):
CREATE TEMP TABLE x (col1 int, col2 text, col3 date); -- use adequate data types!
SELECT a.id, a.name
, json_agg((b.col1, b.col2, b.col3)::x) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
2. Use una subselección
Use una subselección para construir una tabla derivada y hacer referencia a la tabla como un todo . Esto también lleva nombres de columna. Es más detallado, pero no necesita un tipo registrado:
SELECT a.id, a.name
, json_agg((SELECT x FROM (SELECT b.col1, b.col2, b.col3) AS x)) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
SELECT a.id, a.name
, json_agg(json_build_object('col1', b.col1, 'col2', b.col2, 'col3', b.col3)) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
Relacionado:
Similar para jsonb
con las funciones respectivas jsonb_agg()
y jsonb_build_object()
.
Para Postgres 9.5 o posterior también vea la respuesta de a_horse con una nueva variante de sintaxis más corta: Postgres agregó el operador menos -
parajsonb
decir "todas las teclas excepto esta clave" .
Dado que Postgres 10 "excepto varias claves" se implementa con el mismo operador tomando text[]
como segundo operando, como comentó mlt.