PostgreSQL 9.0 trở lên:
Các phiên bản gần đây của Postgres (từ cuối năm 2010) có string_agg(expression, delimiter)
chức năng sẽ thực hiện chính xác những gì câu hỏi yêu cầu, thậm chí cho phép bạn chỉ định chuỗi phân cách:
SELECT company_id, string_agg(employee, ', ')
FROM mytable
GROUP BY company_id;
Postgres 9.0 cũng đã thêm khả năng chỉ định một ORDER BY
mệnh đề trong bất kỳ biểu thức tổng hợp nào ; mặt khác, thứ tự là không xác định. Vì vậy, bây giờ bạn có thể viết:
SELECT company_id, string_agg(employee, ', ' ORDER BY employee)
FROM mytable
GROUP BY company_id;
Hoặc thực sự:
SELECT string_agg(actor_name, ', ' ORDER BY first_appearance)
PostgreSQL 8.4 trở lên:
PostgreQuery 8.4 (năm 2009) đã giới thiệu hàm tổng hợparray_agg(expression)
nối các giá trị thành một mảng. Sau đó array_to_string()
có thể được sử dụng để đưa ra kết quả mong muốn:
SELECT company_id, array_to_string(array_agg(employee), ', ')
FROM mytable
GROUP BY company_id;
string_agg
cho các phiên bản trước 8.4:
Trong trường hợp bất kỳ ai đi qua điều này đang tìm kiếm một shim tương thích cho cơ sở dữ liệu trước 9.0, có thể thực hiện mọi thứ string_agg
trừ ORDER BY
điều khoản.
Vì vậy, với định nghĩa dưới đây, điều này sẽ hoạt động giống như trong DB Postgres 9.x:
SELECT string_agg(name, '; ') AS semi_colon_separated_names FROM things;
Nhưng đây sẽ là một lỗi cú pháp:
SELECT string_agg(name, '; ' ORDER BY name) AS semi_colon_separated_names FROM things;
--> ERROR: syntax error at or near "ORDER"
Đã thử nghiệm trên 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
);
Biến thể tùy chỉnh (tất cả các phiên bản Postgres)
Trước 9.0, không có hàm tổng hợp tích hợp để nối chuỗi. Việc thực hiện tùy chỉnh đơn giản nhất (được đề xuất bởi Vajda Gabo trong bài đăng danh sách gửi thư này , trong số nhiều người khác) là sử dụng textcat
chức năng tích hợp (nằm phía sau ||
toán tử):
CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
Đây là CREATE AGGREGATE
tài liệu.
Điều này chỉ đơn giản là dán tất cả các chuỗi với nhau, không có dấu phân cách. Để có được một "," được chèn vào giữa chúng mà không có nó ở cuối, bạn có thể muốn tạo chức năng nối riêng của mình và thay thế nó cho "textcat" ở trên. Đây là một cái tôi ghép lại và thử nghiệm vào ngày 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;
Phiên bản này sẽ xuất ra dấu phẩy ngay cả khi giá trị trong hàng là null hoặc trống, vì vậy bạn nhận được đầu ra như thế này:
a, b, c, , e, , g
Nếu bạn muốn xóa dấu phẩy thừa để xuất kết quả này:
a, b, c, e, g
Sau đó thêm một ELSIF
kiểm tra cho chức năng như thế này:
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;