본문 바로가기

Server/SQL

[MySQL] GROUP_CONCAT

728x90
반응형

 

요구사항에 아래와 같이 데이터를 뿌려달라는 요청을 받았다.

 

 

 '>' 기호를 제외한 텍스트들은 각자 다른 테이블에 있는 데이터들을 가져온 것이다.

 

처음 요구사항을 봤을 때 이걸 어떤 식으로 만들어야 하는지 감을 못 잡았었다.

여러 쿼리를 찾아서 해결책을 찾았다.

 

GROUP_CONCAT

그룹에서 NULL이 아닌 값들을 연결하여 결과 문자열을 VARCHAR 타입으로 반환해주며,

질의 결과 행이 없거나 NULL 값만 있으면 NULL을 반환해주는 함수이다.

 

기본 구문은 아래와 같다

GROUP_CONCAT([DISTINCT] [expr, column] [ORDER BY column DESC] [SEPARATOR '구분자'])

 

나같은 경우는 2개의 테이블의 컬럼 값끼리 비교하여 GROUP_CONCAT으로 만들어주고 

마지막에 또 다른 테이블의 관련 컬럼 값을 가져와 CONCAT으로 붙여주었다.

 

SELECT
(
    SELECT 
        CONCAT(GROUP_CONCAT(F.ITEM_NAME ORDER BY UP_FLD_DEPTH SEPARATOR '>'), '>', B.BRD_NAME)
    FROM
        FOLDER_MAPPING M,
        FOLDER_TARGET F
    WHERE B.FLD_ID = M.FLD_ID
        AND F.TRGT_ID = M.UP_FLD_ID
        AND F.TRGT_COL_NAME = 'FLD_NAME'
        AND F.LANG_SE_CD =  'ko' 
) FLD_LOC_NAME
FROM ARTICLE A, BOARD B
WHRER A.BRD_ID = B.BRD_ID

실제 쿼리는 더 길지만 필요한 부분만 잘라서 작성하였다.

보시다시피 스칼라 서브쿼리로 만들어 넣어 주었다.

 

BOARD 테이블의 FLD_ID 값과 FOLDER_MAPPING 테이블의 FLD_ID 값을 조인한다.

위 조인 결과의 FOLDER_MAPPING 테이블의 UP_FLD_ID 값과 FOLDER_TARGET 테이블의 TRGT_ID 값을 조인한다.

위 조인 결과의 FOLDER_TARGET 테이블의 TRGT_COL_NAME 컬럼 값과 LANG_SE_CD 컬럼 값이 명시되어 있는 값과 일치하는 결과 값을 SELECT 한다.

SELECT 된 값, FOLDER_TARGET 테이블의 ITEM_NAME 컬럼 값을 오름차순으로 한 컬럼에 정렬해 넣어준다.

다시 거기다 CONCAT을 통해 BOARD 테이블의 BRD_NAME 컬럼 값을 마지막에 넣어준다.

 

나름 내가 이해한 부분을 풀어썼는데 개판인 것 같다.

어쨌든 아래는 DB 테이블이다.

FOLDER_MAPPING 테이블

FOLDER_MAPPING 테이블 값들이다. BOARD 테이블의 FLD_ID 값을 기준으로 하여 조회가 되었다.

GROUP_CONCAT 부분의 " F.ITEM_NAME ORDER BY UP_FLD_DEPTH SEPARATOR '>' " 에서 사용이 되는 것을 볼 수 있다.

UP_FLD_DEPTH 컬럼 값의 오름차순으로 하여 UP_FLD_ID 값에 대응되는 데이터에다가 '>'  구분자를 넣어주는 식이다.

여기서 UP_FLD_ID에 대응되는 값은 FOLDER_TARGET 테이블의 TRGT_ID 값과 비교하여 나온 ITEM_NAME 컬럼 값이 되겠다.

 

SELECT 문으로 조회를 해보았다.

 

TRGT_ID = 'BFCC300191226'

 

UP_FLD_DEPTH 값이 1에 해당하는 UP_FLD_ID = TRGT_ID 값이 조인되는 결과 값이다.

ITEM_NAME은 '게시판'

 

TRGT_ID = 'BF5115279499101001211'

 

UP_FLD_DEPTH 값이 2에 해당하는 UP_FLD_ID = TRGT_ID 값이 조인되는 결과 값이다.

ITEM_NAME은 '정보'

 

여기까지 GROUP_CONCAT으로 만들어 내면 '게시판>정보' 와 같은 값이 만들어지는 것이다.

이제 여기다 다시 CONCAT을 이용해 마지막 부분엔 게시물 이름을 넣어주는 것이다.

 

FLD_ID = 'BF5115279499101001211'

게시물 이름 역시 맨 처음 사용된 FLD_ID에 해당하는 BRD_NAME 컬럼 값을 넣어주면 되겠다.

BRD_NAME은 '인사알림방'

 

그럼 아래와 같이 조회가 되어 나오는 모습이다

실제로 조회된 화면


DB 쿼리문은 항상 어렵게 느껴지며, GROUP_CONCAT과 같은 처음 마주친 함수들이 아직 많이 있어 머리가 아프다.

그리고 이해를 하고 쿼리를 짰다고 생각하지만 막상 그 쿼리를 다시 보면 바로 이해가 안돼 난처했던 적이 번번히 있었던 것 같다. 조만간 인프런에서 쿼리문과 관련된 강의를 봐야겠다.

728x90
반응형