MySQL의 CONCAT에서 GROUP_CONCAT를 사용하는 방법


117

MySQL에 다음 데이터가있는 테이블이있는 경우 :

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

다음 형식으로 어떻게 가져 옵니까?

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


를 사용해야한다고 생각합니다 GROUP_CONCAT. 하지만 어떻게 작동하는지 잘 모르겠습니다.

답변:


160
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;

여기에서 구현 된 것을 볼 수 있습니다. Sql Fiddle Demo . 정확히 필요한 것.

두 단계로 분할을 업데이트 합니다. 먼저 고유 [Name, id]에 대한 모든 값 (쉼표로 구분)을 갖는 테이블을 얻습니다. 그런 다음 얻은 테이블에서 모든 이름과 값을 각 고유 ID에 대한 단일 값으로 가져옵니다. 여기에 설명 된 내용을 참조하십시오. SQL Fiddle 데모 (두 개의 결과 집합이 있으므로 아래로 스크롤)

편집 질문을 읽는데 실수가있어서 아이디로만 그룹화했습니다. 그러나 두 개의 group_contacts가 필요합니다 (값이 이름과 ID로 그룹화되고 그 다음에는 모두 ID로 그룹화 됨). 이전 답변은

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

여기에서 구현 된 것을 볼 수 있습니다. SQL Fiddle 데모


이것은 Biswa가 요청한 것을 제공하지 않습니다.
eisberg

3
나는 사람들에게 한 종류의 분리기 만 사용하는 것이 불리 할 수 ​​있음을 경고하는 것이 중요하다고 생각합니다. (,)과 값 분리기 콤마로 남아있을 수있다 ()는 I 세미콜론로서 "이름"을 제안 세퍼레이터
Fandi Susanto

4
또한 GROUP_CONCAT자동으로 출력을 group_concat_max_len. SET group_concat_max_len=...도움이 될 것이지만 어쨌든 반환 된 (byte?) 길이가보다 작은 지 확인하는 것이 좋습니다 group_concat_max_len.
tuomassalo

2
group_concat은 단일 NULL 값을 만나면이를 포함하는 전체 행을 생략합니다. 여기서 두 번째 경고에서이 문제를 해결합니다 .
MatrixManAtYrService

1
대답에 주어진 SQL Fiddle 링크에 문제가있는 사람이 있다면. Working Fiddle은 여기에 있습니다 : sqlfiddle.com/#!9/42f994/601/0
Hitesh

21

시험:

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;

SQL Fiddle : http://sqlfiddle.com/#!2/b5abe/9/0


2
예 eisberg +1. 귀하의 답변은 매우 정확하고 빠릅니다. 첫 번째 답변에서 실수를 저질렀습니다
Sami

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

7
답변에 설명을 추가 할 수 있다면 좋을 것입니다. 이것은 이것과 미래의 답변을 개선하기위한 제안입니다. 감사!
Luís Cruz

5

우선, 고유하지 않은 ID를 갖는 이유는 알 수 없지만 다른 테이블에 연결되는 ID 인 것 같습니다. 둘째, 서버를 능가하는 하위 쿼리가 필요하지 않습니다. 이렇게 하나의 쿼리로 수행합니다.

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

빠르고 정확한 결과를 얻고 SEPARATOR "|"로 결과를 나눌 수 있습니다. 저는 항상이 구분 기호를 사용합니다. 문자열 내에서 찾을 수 없기 때문에 고유합니다. A가 두 개 있으면 문제가 없으며 값만 식별합니다. 또는 편지와 함께 열을 하나 더 가질 수 있습니다. 이렇게 :

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

캐스트 또는 변환을 사용해야합니다. 그렇지 않으면 BLOB가 반환됩니다.

결과는

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

결과를 다시 한번 파이썬이나 자바와 같은 프로그램으로 처리해야합니다.


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

내 테이블 이름은 test이고 연결을 위해 For XML Path ( '') 구문을 사용합니다. stuff 함수는 문자열을 다른 문자열에 삽입합니다. 시작 위치의 첫 번째 문자열에서 지정된 길이의 문자를 삭제 한 다음 두 번째 문자열을 시작 위치의 첫 번째 문자열에 삽입합니다.

STUFF 함수는 다음과 같습니다. STUFF (문자 표현식, 시작, 길이, 문자 _ 표현식)

character_expression 문자 데이터의 식입니다. character_expression은 상수, 변수 또는 문자 또는 이진 데이터의 열일 수 있습니다.

start 삭제 및 삽입을 시작할 위치를 지정하는 정수 값입니다. 시작 또는 길이가 음수이면 널 문자열이 리턴됩니다. start가 첫 번째 character_expression보다 길면 null 문자열이 반환됩니다. start는 bigint 유형일 수 있습니다.

length 삭제할 문자 수를 지정하는 정수입니다. 길이가 첫 번째 character_expression보다 길면 마지막 character_expression의 마지막 문자까지 삭제됩니다. length는 bigint 유형일 수 있습니다.


0

SELECT id, Group_concat ( column) FROM (SELECT id, Concat ( name, ':', Group_concat ( value)) AS column FROM mytbl GROUP BY id, name) tbl GROUP BY id;

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.