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 TYPEdeclaració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 jsonbcon 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.