Sayangnya, tidak ada ketentuan dalam sintaks SQL untuk mengatakan "semua kolom kecuali kolom yang satu ini" . Anda dapat mencapai tujuan Anda dengan mengeja daftar kolom yang tersisa dalam ekspresi tipe baris :
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;
Itu pendek untuk bentuk yang lebih eksplisit: . ROW
(b.col1, b.col2, b.col3)
Namun, nama kolom tidak dipertahankan dalam ekspresi tipe baris. Anda mendapatkan nama kunci umum dalam objek JSON dengan cara ini. Saya melihat 3 opsi untuk mempertahankan nama kolom asli:
1. Pilih tipe yang terdaftar
Pilih tipe baris yang terkenal (terdaftar). Suatu tipe terdaftar untuk setiap tabel atau tampilan yang ada atau dengan CREATE TYPE
pernyataan eksplisit . Anda mungkin menggunakan tabel sementara untuk solusi ad-hoc (berlaku selama durasi sesi):
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. Gunakan subselect
Gunakan subselect untuk membangun tabel turunan dan referensi tabel secara keseluruhan . Ini juga membawa nama kolom. Ini lebih bertele-tele, tetapi Anda tidak perlu tipe terdaftar:
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;
Terkait:
Mirip untuk jsonb
masing-masing fungsi jsonb_agg()
dan jsonb_build_object()
.
Untuk Postgres 9.5 atau yang lebih baru, lihat juga jawaban a_horse dengan varian sintaks baru yang lebih pendek: Postgres menambahkan operator minus -
untukjsonb
mengatakan "semua kunci kecuali kunci yang satu ini" .
Karena Postgres 10 "kecuali beberapa kunci" diimplementasikan dengan operator yang sama dengan text[]
mlt seperti - operan 2 berkomentar.