แต่น่าเสียดายที่ไม่มีบทบัญญัติในไวยากรณ์ 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. ใช้การเลือกย่อย
ใช้ subselect เพื่อสร้างตารางที่ได้มาและการอ้างอิงตารางเป็นทั้ง นอกจากนี้ยังมีชื่อคอลัมน์ มันละเอียดมากขึ้น แต่คุณไม่จำเป็นต้องมีประเภทที่ลงทะเบียน:
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 แสดงความคิดเห็น