MySQL có GROUP_CONCAT()
chức năng cho phép chúng tôi trả về các cột từ truy vấn dưới dạng danh sách được phân tách.
Nó trả về một kết quả chuỗi với phần tử không phải là NULL
được nối giá trị từ một nhóm.
Cú pháp
Cú pháp như sau:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val])
Ví dụ
Giả sử chúng ta chạy truy vấn sau:
SELECT PetName
FROM Pets;
Và chúng tôi nhận được kết quả sau:
+---------+ | PetName | +---------+ | Fluffy | | Fetch | | Scratch | | Wag | | Tweet | | Fluffy | | Bark | | Meow | +---------+ 8 rows in set (0.00 sec)
Chúng ta có thể sử dụng GROUP_CONCAT()
để trả về tất cả các hàng đó dưới dạng danh sách được phân tách.
Để thực hiện việc này, chúng ta cần chuyển PetName
làm đối số cho GROUP_CONCAT()
chức năng:
SELECT GROUP_CONCAT(PetName)
FROM Pets;
Kết quả:
+-------------------------------------------------+ | GROUP_CONCAT(PetName) | +-------------------------------------------------+ | Fluffy,Fetch,Scratch,Wag,Tweet,Fluffy,Bark,Meow | +-------------------------------------------------+ 1 row in set (0.01 sec)
Đặt hàng
Chúng ta có thể sử dụng ORDER BY
mệnh đề đặt hàng đầu ra của hàm này:
SELECT GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets;
Kết quả:
Bark,Fetch,Fluffy,Fluffy,Meow,Scratch,Tweet,Wag
Lưu ý rằng điều này chỉ sắp xếp đầu ra của GROUP_CONCAT()
chức năng - nó hoàn toàn độc lập với bất kỳ thứ tự nào được áp dụng cho SELECT
tuyên bố chính nó.
DISTINCT
Mệnh đề
Chúng tôi có thể sử dụng DISTINCT
mệnh đề để trả về các giá trị duy nhất. Nói cách khác, nếu có các giá trị trùng lặp, chỉ một lần xuất hiện được trả về:
SELECT GROUP_CONCAT(DISTINCT PetName ORDER BY PetName ASC)
FROM Pets;
Kết quả:
Bark,Fetch,Fluffy,Meow,Scratch,Tweet,Wag
Trong trường hợp này, Fluffy
chỉ xuất hiện một lần. Khi chúng tôi chạy nó mà không có DISTINCT
mệnh đề, Fluffy
xuất hiện hai lần.
Thay đổi Dấu phân tách
Theo mặc định, danh sách sử dụng dấu phẩy làm dấu phân cách. Nhưng chúng tôi có thể thay đổi điều này nếu chúng tôi muốn:
SELECT GROUP_CONCAT(PetName SEPARATOR '-')
FROM Pets;
Kết quả:
Fluffy-Fetch-Scratch-Wag-Tweet-Fluffy-Bark-Meow
Chúng tôi thậm chí có thể sử dụng một chuỗi trống để loại bỏ tất cả các dấu phân cách (để các giá trị được nối với nhau):
SELECT GROUP_CONCAT(PetName SEPARATOR '')
FROM Pets;
Và chúng tôi nhận được kết quả sau:
FluffyFetchScratchWagTweetFluffyBarkMeow
Kết quả truy vấn được nhóm
Chúng tôi có thể bao gồm GROUP_CONCAT()
trong một truy vấn với GROUP BY
mệnh đề để đạt được kết quả như sau:
SELECT
PetTypeId,
GROUP_CONCAT(PetName ORDER BY PetName ASC)
FROM Pets
GROUP BY PetTypeId
ORDER BY PetTypeId;
Kết quả:
+-----------+--------------------------------------------+ | PetTypeId | GROUP_CONCAT(PetName ORDER BY PetName ASC) | +-----------+--------------------------------------------+ | 1 | Tweet | | 2 | Fluffy,Meow,Scratch | | 3 | Bark,Fetch,Fluffy,Wag | +-----------+--------------------------------------------+
Trong cơ sở dữ liệu của tôi, tên loại vật nuôi thực tế nằm trong một bảng khác được gọi là PetTypes
. Do đó, chúng tôi có thể chạy INNER JOIN
trên PetTypes
bảng để lấy tên loại vật nuôi thực tế:
SELECT
pt.PetType,
GROUP_CONCAT(p.PetName ORDER BY p.PetName ASC)
FROM Pets p
INNER JOIN PetTypes pt ON
p.PetTypeId = pt.PetTypeId
GROUP BY pt.PetType
ORDER BY pt.PetType ASC;
Kết quả:
+---------+------------------------------------------------+ | PetType | GROUP_CONCAT(p.PetName ORDER BY p.PetName ASC) | +---------+------------------------------------------------+ | Bird | Tweet | | Cat | Fluffy,Meow,Scratch | | Dog | Bark,Fetch,Fluffy,Wag | +---------+------------------------------------------------+
Giới hạn về độ dài
GROUP_CONCAT()
Đầu ra của ‘s bị cắt ngắn đến độ dài tối đa được cung cấp bởi group_concat_max_len
biến hệ thống, có giá trị mặc định là 1024
. Giá trị có thể được đặt cao hơn, mặc dù độ dài tối đa hiệu dụng của giá trị trả về bị giới hạn bởi giá trị của max_allowed_packet
.
Bạn có thể kiểm tra giá trị hiện tại như sau:
SHOW VARIABLES LIKE '%group_concat%';
Cú pháp để thay đổi giá trị này như sau:
SET [GLOBAL | SESSION] group_concat_max_len = val;
Ở đâu val
là một số nguyên không dấu.