PostgreSQL 9.0 หรือใหม่กว่า:
รุ่นล่าสุดของ Postgres (ตั้งแต่ปลายปี 2010) มีstring_agg(expression, delimiter)
ฟังก์ชันที่จะทำตามที่คำถามที่ต้องการแม้แต่ให้คุณระบุสตริงตัวคั่น:
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Postgres 9.0 ยังเพิ่มความสามารถในการระบุORDER BY
ข้อในการแสดงออกใด ๆ รวม ; มิฉะนั้นการสั่งซื้อจะไม่ได้กำหนด ดังนั้นตอนนี้คุณสามารถเขียน:
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
หรือแน่นอน:
SELECT string_agg(actor_name, ', ' ORDER BY first_appearance)
PostgreSQL 8.4 หรือใหม่กว่า:
PostgreSQL 8.4 (ในปี 2009) เปิดตัวฟังก์ชั่นการรวมarray_agg(expression)
ซึ่งเชื่อมต่อค่าลงในอาร์เรย์ จากนั้นarray_to_string()
สามารถใช้เพื่อให้ผลลัพธ์ที่ต้องการ:
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
string_agg
สำหรับเวอร์ชั่นก่อน 8.4:
ในกรณีที่ทุกคนเจอการมองหา shim ที่เข้ากันได้สำหรับฐานข้อมูล pre-9.0 คุณสามารถใช้ทุกอย่างได้string_agg
ยกเว้นORDER BY
ข้อ
ดังนั้นด้วยคำจำกัดความด้านล่างนี้ควรทำงานเหมือนกับใน 9.x Postgres DB:
SELECT string_agg(name, '; ') AS semi_colon_separated_names FROM things;
แต่นี่จะเป็นข้อผิดพลาดทางไวยากรณ์:
SELECT string_agg(name, '; ' ORDER BY name) AS semi_colon_separated_names FROM things;
--> ERROR: syntax error at or near "ORDER"
ทดสอบกับ PostgreSQL 8.3
CREATE FUNCTION string_agg_transfn(text, text, text)
RETURNS text AS
$$
BEGIN
IF $1 IS NULL THEN
RETURN $2;
ELSE
RETURN $1 || $3 || $2;
END IF;
END;
$$
LANGUAGE plpgsql IMMUTABLE
COST 1;
CREATE AGGREGATE string_agg(text, text) (
SFUNC=string_agg_transfn,
STYPE=text
);
รูปแบบที่กำหนดเอง (ทุกรุ่น Postgres)
ก่อนหน้า 9.0 ไม่มีฟังก์ชันการรวมในตัวเพื่อเชื่อมสตริงเข้าด้วยกัน การปรับใช้ที่ง่ายที่สุด ( แนะนำโดย Vajda Gabo ในโพสต์จดหมายข่าวนี้และอื่น ๆ อีกมากมาย) คือการใช้textcat
ฟังก์ชั่นในตัว(ซึ่งอยู่ด้านหลังตัว||
ดำเนินการ):
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
นี่คือCREATE AGGREGATE
เอกสารประกอบ
นี่เป็นการรวมสตริงทั้งหมดเข้าด้วยกันโดยไม่มีตัวคั่น เพื่อที่จะได้ "," แทรกอยู่ระหว่างพวกเขาโดยไม่ต้องมีในตอนท้ายคุณอาจต้องการที่จะทำให้ฟังก์ชั่นการเชื่อมต่อของคุณเองและแทนที่มันสำหรับ "textcat" ข้างต้น นี่คือสิ่งที่ฉันรวบรวมและทดสอบใน 8.3.12:
CREATE FUNCTION commacat(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;
รุ่นนี้จะส่งออกเครื่องหมายจุลภาคแม้ว่าค่าในแถวจะว่างเปล่าหรือว่างเปล่าดังนั้นคุณจะได้ผลลัพธ์ดังนี้:
a, b, c, , e, , g
หากคุณต้องการลบเครื่องหมายจุลภาคพิเศษเพื่อแสดงผลนี้:
a, b, c, e, g
จากนั้นเพิ่มการELSIF
ตรวจสอบไปยังฟังก์ชันดังนี้:
CREATE FUNCTION commacat_ignore_nulls(acc text, instr text) RETURNS text AS $$
BEGIN
IF acc IS NULL OR acc = '' THEN
RETURN instr;
ELSIF instr IS NULL OR instr = '' THEN
RETURN acc;
ELSE
RETURN acc || ', ' || instr;
END IF;
END;
$$ LANGUAGE plpgsql;