К сожалению, в синтаксисе SQL не предусмотрено выражение «все столбцы, кроме этого одного столбца» . Вы можете достичь своей цели, изложив оставшийся список столбцов в выражении типа строки :
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;
Это коротко для более явной формы: . ROW
(b.col1, b.col2, b.col3)
Однако имена столбцов не сохраняются в выражениях типа строки. Таким образом вы получаете общие имена ключей в объекте JSON. Я вижу 3 варианта сохранения оригинальных имен столбцов:
1. Приведение к зарегистрированному типу
Приведение к известному (зарегистрированному) типу строки. Тип регистрируется для каждой существующей таблицы или представления или с явным CREATE TYPE
оператором. Вы можете использовать временную таблицу для специального решения (действует в течение всего сеанса):
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. Используйте подвыбор
Используйте вложенный выбор для построения производной таблицы и ссылки на таблицу в целом . Это также несет имена столбцов. Это более многословно, но вам не нужен зарегистрированный тип:
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;
Связанный:
Аналогично для jsonb
соответствующих функций jsonb_agg()
и jsonb_build_object()
.
Для Postgres 9.5 или более поздней версии также увидеть ответ a_horse в с новым вариантом короче синтаксис: Postgres добавлен оператор минус -
дляjsonb
сказать «все клавиши , кроме этого одного ключа» .
Поскольку Postgres 10 «кроме нескольких ключей» реализован с тем же оператором, text[]
что и второй операнд - как в комментариях к MLT.