[DB] 조건에 맞는 값 그룹 형태로 출력 (GROUP_CONCAT)
개요
특정 컬럼의 목록을 하나의 그룹으로 조회해야 하는 상황이 종종 발생합니다.
아래는 가상의 테이블 스키마 구조로, 납품 업체와 제휴를 맺고 있는 파트너사의 가맹점들이 상품 발주 요청을 관리하는 테이블입니다.
CREATE TABLE `order_form` (
`order_form_id` int NOT NULL AUTO_INCREMENT,
`partner_name` varchar(50) NOT NULL,
`partner_code` varchar(20) NOT NULL,
`product_name` varchar(50) NOT NULL,
`request_dt` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`order_form_id`)
) ENGINE=InnoDB;
동일한 파트너사에 다양한 가맹점들이 존재할 수 있으며, 각 가맹점은 고유한 키(partner_code)를 가지고 있습니다.
예를 들어, 다음과 같은 데이터가 저장되어 있다고 가정해 보겠습니다.
INSERT INTO order_form (partner_name, partner_code, product_name) VALUES ('스타벅스', 'SB01', '설탕');
INSERT INTO order_form (partner_name, partner_code, product_name) VALUES ('스타벅스', 'SB01', '시럽');
INSERT INTO order_form (partner_name, partner_code, product_name) VALUES ('스타벅스', 'SB02', '에스프레소 원두');
INSERT INTO order_form (partner_name, partner_code, product_name) VALUES ('투썸플레이스', 'TS01', '계량스푼');

하나의 가맹점이라는 조건을 조회하려면 다음과 같은 쿼리를 사용할 수 있습니다.
SELECT partner_code
, COUNT(partner_code) AS count
FROM order_form
GROUP BY partner_code;

그런데 각각의 가맹점마다 요청한 상품 목록들을 함께 보여주어야 하는 상황이 생겨버렸습니다.
이처럼 각 가맹점마다 요청한 상품 목록을 함께 보여주어야 할 때 사용하기 유용한 GROUP_CONCAT 함수가 있습니다.
GROUP_CONCAT 함수는 그룹화된 항목의 특정 항목을 연결된 문자열로 반환합니다.
https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions.html#function_group-concat
MySQL :: MySQL 8.0 Reference Manual :: 14.19.1 Aggregate Function Descriptions
MySQL 8.0 Reference Manual / ... / Functions and Operators / Aggregate Functions / Aggregate Function Descriptions 14.19.1 Aggregate Function Descriptions This section describes aggregate functions that operate on sets of values. They are
dev.mysql.com
별도의 설정을 하지 않은 경우에는 기본 구분자로 쉼표(', ')를 사용하여 결과를 반환합니다.
SELECT partner_code,
COUNT(partner_code) AS count,
GROUP_CONCAT(product_name) AS product_name_group
FROM order_form
GROUP BY partner_code;

추가적인 기능들도 더러 제공하고 있습니다.
중복된 상품명 제거 (DISTINCT)
중복된 상품명을 한 번만 보이게 하려면 DISTINCT 키워드를 사용할 수 있습니다.
SELECT partner_code
, COUNT(partner_code) AS count
, GROUP_CONCAT(DISTINCT product_name) AS product_name_group
FROM order_form
GROUP BY partner_code;
AS-IS:

TO-BE:

문자열 구분자 변경 (SEPARATOR)
문자열 구분자를 변경하려면 SEPARATOR 키워드를 사용할 수 있습니다.
예를 들어, ' ### ' 구분자를 사용하고 싶다면 다음과 같이 쿼리를 작성하면 됩니다.
SELECT partner_code
, COUNT(partner_code) AS count
, GROUP_CONCAT(DISTINCT product_name SEPARATOR ' ### ') AS product_name_group
FROM order_form
GROUP BY partner_code;

정렬 순서 변경 (ORDER BY)
연결된 문자열의 정렬 순서를 변경하려면 ORDER BY 키워드를 사용할 수 있습니다.
예를 들어, 상품명을 내림차순으로 정렬하려면 다음과 같이 작성하면 됩니다.
SELECT partner_code
, COUNT(partner_code) AS count
, GROUP_CONCAT(DISTINCT product_name
ORDER BY product_name DESC
SEPARATOR ' ### ') AS product_name_group
FROM order_form
GROUP BY partner_code;
