Cách sử dụng GROUP_CONCAT trong CONCAT trong MySQL


116

Nếu tôi có một bảng với dữ liệu sau trong MySQL:

id       Name       Value
1          A          4
1          A          5
1          B          8
2          C          9

Làm thế nào để tôi có được nó trong định dạng sau đây?

id         Column
1          A:4,5,B:8
2          C:9


Tôi nghĩ rằng tôi phải sử dụng GROUP_CONCAT. Nhưng tôi không chắc nó hoạt động như thế nào.

Câu trả lời:


159
select id, group_concat(`Name` separator ',') as `ColumnName`
from
(
  select 
    id, 
    concat(`Name`, ':', group_concat(`Value` separator ',')) as `Name`
  from mytbl
  group by 
    id, 
    `Name`
) tbl
group by id;

Bạn có thể thấy nó được thực hiện ở đây: Sql Fiddle Demo . Chính xác những gì bạn cần.

Cập nhật Chia tách theo hai bước. Đầu tiên chúng ta nhận được một bảng có tất cả các giá trị (được phân tách bằng dấu phẩy) dựa vào [Tên, id] duy nhất. Sau đó, từ bảng thu được, chúng tôi nhận được tất cả các tên và giá trị dưới dạng một giá trị theo từng id duy nhất Xem phần này được giải thích ở đây SQL Fiddle Demo (cuộn xuống vì nó có hai tập kết quả)

Chỉnh sửa Có một lỗi khi đọc câu hỏi, tôi chỉ được nhóm theo id. Nhưng cần có hai nhóm_contacts nếu (Các giá trị được ghép nối được nhóm theo Tên và id và sau đó trên tất cả theo id). Câu trả lời trước là

select 
id,group_concat(concat(`name`,':',`value`) separator ',')
as Result from mytbl group by id

Bạn có thể thấy nó được triển khai ở đây: SQL Fiddle Demo


Điều này không đưa ra những gì Biswa yêu cầu.
eisberg

3
Tôi nghĩ điều quan trọng là phải cảnh báo mọi người rằng chỉ sử dụng một loại dải phân cách có thể là bất lợi. Tôi đề nghị đặt dấu phân cách "tên" là dấu chấm phẩy (;) và dấu tách giá trị có thể vẫn là dấu phẩy (,)
Fandi Susanto

4
Cũng xin lưu ý rằng GROUP_CONCATcó thể âm thầm cắt đầu ra của nó group_concat_max_len. SET group_concat_max_len=...sẽ giúp ích, nhưng dù sao cũng nên kiểm tra xem độ dài (byte?) được trả về có nhỏ hơn không group_concat_max_len.
tuomassalo

2
Cũng lưu ý rằng group_concat gặp một giá trị NULL duy nhất, nó sẽ bỏ qua toàn bộ hàng có chứa nó. Tôi làm việc xung quanh điều này trong cảnh báo thứ hai ở đây .
MatrixManAtYrService

1
Nếu bất cứ ai gặp phải vấn đề với liên kết SQL Fiddle được đưa ra trong câu trả lời. Fiddle làm việc có tại đây: sqlfiddle.com/#!9/42f994/601/0
Hitesh

21

Thử:

CREATE TABLE test (
  ID INTEGER,
  NAME VARCHAR (50),
  VALUE INTEGER
);

INSERT INTO test VALUES (1, 'A', 4);
INSERT INTO test VALUES (1, 'A', 5);
INSERT INTO test VALUES (1, 'B', 8);
INSERT INTO test VALUES (2, 'C', 9);

SELECT ID, GROUP_CONCAT(NAME ORDER BY NAME ASC SEPARATOR ',')
FROM (
  SELECT ID, CONCAT(NAME, ':', GROUP_CONCAT(VALUE ORDER BY VALUE ASC SEPARATOR ',')) AS NAME
  FROM test
  GROUP BY ID, NAME
) AS A
GROUP BY ID;

Câu đố SQL: http://sqlfiddle.com/#!2/b5abe/9/0


2
Có eisberg +1. Câu trả lời của bạn là khá nhiều chính xác và sớm hơn. Tôi đã mắc lỗi trong lần trả lời đầu tiên
Sami

8
SELECT ID, GROUP_CONCAT(CONCAT_WS(':', NAME, VALUE) SEPARATOR ',') AS Result 
FROM test GROUP BY ID

7
Sẽ thật tuyệt nếu bạn có thể thêm một số mô tả vào câu trả lời của bạn. Đây là một gợi ý để cải thiện câu trả lời này và trong tương lai. Cảm ơn!
Luís Cruz

5

Trước hết, tôi không thấy lý do để có một ID không phải là duy nhất, nhưng tôi đoán đó là một ID kết nối với một bảng khác. Thứ hai, không cần truy vấn con, đánh bại máy chủ. Bạn làm điều này trong một truy vấn, như thế này

SELECT id,GROUP_CONCAT(name, ':', value SEPARATOR "|") FROM sample GROUP BY id

Bạn nhận được kết quả nhanh và chính xác và bạn có thể chia kết quả cho SEPARATOR đó "|". Tôi luôn sử dụng dấu phân cách này, vì không thể tìm thấy nó trong một chuỗi, vì nó là duy nhất. Không có vấn đề gì khi có hai chữ A, bạn chỉ xác định giá trị. Hoặc bạn có thể có thêm một colum, với chữ cái, thậm chí còn tốt hơn. Như thế này :

SELECT id,GROUP_CONCAT(DISTINCT(name)), GROUP_CONCAT(value SEPARATOR "|") FROM sample GROUP BY name

2
 SELECT id, GROUP_CONCAT(CONCAT_WS(':', Name, CAST(Value AS CHAR(7))) SEPARATOR ',') AS result 
    FROM test GROUP BY id

bạn phải sử dụng cast hoặc convert, nếu không sẽ được trả lại BLOB

kết quả là

id         Column
1          A:4,A:5,B:8
2          C:9

bạn phải xử lý kết quả một lần nữa bằng chương trình như python hoặc java


0

IF OBJECT_ID('master..test') is not null Drop table test

CREATE TABLE test (ID INTEGER, NAME VARCHAR (50), VALUE INTEGER );
INSERT INTO test VALUES (1, 'A', 4);
INSERT INTO test VALUES (1, 'A', 5);
INSERT INTO test VALUES (1, 'B', 8);
INSERT INTO test VALUES (2, 'C', 9);

select distinct NAME , LIST = Replace(Replace(Stuff((select ',', +Value from test where name = _a.name for xml path('')), 1,1,''),'<Value>', ''),'</Value>','') from test _a order by 1 desc

Tên bảng của tôi là thử nghiệm và để ghép nối, tôi sử dụng cú pháp For XML Path (''). Hàm Stuff chèn một chuỗi vào một chuỗi khác. Nó xóa một độ dài ký tự được chỉ định trong chuỗi đầu tiên ở vị trí bắt đầu và sau đó chèn chuỗi thứ hai vào chuỗi đầu tiên ở vị trí bắt đầu.

Các hàm STUFF trông như thế này: STUFF (character_expression, start, length, character_expression)

character_expression Là một biểu thức của dữ liệu ký tự. character_expression có thể là hằng số, biến hoặc cột của dữ liệu nhị phân hoặc ký tự.

start Là một giá trị nguyên xác định vị trí để bắt đầu xóa và chèn. Nếu bắt đầu hoặc độ dài là âm, một chuỗi null được trả về. Nếu bắt đầu dài hơn ký tự đầu tiên, chuỗi null được trả về. bắt đầu có thể là loại bigint.

chiều dài Là một số nguyên chỉ định số lượng ký tự cần xóa. Nếu độ dài dài hơn ký tự đầu tiên, việc xóa xảy ra cho đến ký tự cuối cùng trong ký tự cuối cùng. chiều dài có thể là loại bigint.


0

CHỌN id, Group_concat ( column) TỪ (id id, Concat ( name, ':', Group_concat ( value)) NHƯ column TỪ NHÓM mytbl BY id, name) tbl GROUP BY id;

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.