Câu hỏi ban đầu là cơ sở dữ liệu cụ thể, nhưng có lẽ đây là một nơi tốt để bao gồm một câu trả lời chung chung hơn. Đó là một câu hỏi phổ biến. Khái niệm mà bạn đang mô tả thường được gọi là 'Kết nối nhóm'. Không có giải pháp tiêu chuẩn nào trong SQL-92 hoặc SQL-99. Vì vậy, bạn sẽ cần một giải pháp dành riêng cho nhà cung cấp.
- MySQL - Sử dụng hàm GROUP_CONCAT tích hợp sẵn. Trong ví dụ của bạn, bạn sẽ muốn một cái gì đó như thế này:
select o.ID, o.Address, o.OtherDetails, GROUP_CONCAT( concat(e.firstname, ' ', e.lastname) ) as Employees from employees e inner join organization o on o.org_id=e.org_id group by o.org_id
- PostgreSQL - PostgreSQL 9.0 bây giờ cũng đơn giản không kém khi string_agg (biểu thức, dấu phân cách) được tích hợp sẵn. Đây là với 'dấu phẩy-khoảng trắng' giữa các phần tử:
select o.ID, o.Address, o.OtherDetails, STRING_AGG( (e.firstname || ' ' || e.lastname), ', ' ) as Employees from employees e inner join organization o on o.org_id=e.org_id group by o.org_id
PostgreSQL trước 9.0 cho phép bạn xác định các hàm tổng hợp của riêng mình với CREATE AGGREGATE. Công việc nhiều hơn một chút so với MySQL, nhưng linh hoạt hơn nhiều. Xem điều này bài đăng khác để biết thêm chi tiết. (Tất nhiên PostgreSQL 9.0 trở lên cũng có tùy chọn này.)
-
Oracle - cùng một ý tưởng bằng cách sử dụng LISTAGG .
-
Máy chủ MS SQL - cùng một ý tưởng bằng cách sử dụng STRING_AGG
-
Giải pháp dự phòng - trong các công nghệ cơ sở dữ liệu khác hoặc trong các phiên bản rất cũ của các công nghệ được liệt kê ở trên, bạn không có các chức năng nối nhóm này. Trong trường hợp đó, hãy tạo một thủ tục được lưu trữ lấy org_id làm đầu vào và xuất ra các tên nhân viên được nối. Sau đó, sử dụng thủ tục được lưu trữ này trong truy vấn của bạn. Một số câu trả lời khác ở đây bao gồm một số chi tiết về cách viết các thủ tục được lưu trữ như thế này.
select o.ID, o.Address, o.OtherDetails, MY_CUSTOM_GROUP_CONCAT_PROCEDURE( o.ID ) as Employees from organization o