На жаль, у синтаксисі 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[]
як 2-й операнд - як коментує mlt.