본문 바로가기
공부/Database

LISTAGG Function

by 무심한고라니 2021. 1. 12.

일전에 SQL 스터디를 하며 오라클의 LISTAGG 함수[1]에 대해 들어본 적은 있었습니다. 하지만 일하며 직접 사용해본 적이 없어서인지 들으면서도 언제 사용하면 좋을지에 대해선 짐작이 안 갔습니다. 마침 최근 프로젝트에서 LISTAGG 함수를 이용한 경험을 하게 되어 기초적일 수 있지만 기억에 남기기 위해 글을 작성합니다. 글에 대한 피드백이 있다면 댓글 남겨주시면 감사하겠습니다.

 

_____

내가 작업 중인 화면은 대략 아래와 비슷했다.

 

 

설명하자면, 특정일자로 조회하면 좌측에 해당 일자에 대한 'K리그 경기 일정'이 조회된다. 이 목록에서 특정 경기를 선택하면 우측 상단의 '협회 등록 선수 명단'에서 해당 경기를 뛴 선수에 대해 체크 박스 표시가 된다. 추가적으로 테이블 설계는 다음과 같았다.

 

 

이때 내 고민은 조회 시 테이블에서 어떻게 데이터를 가져와야 할까[2] 하는 것이었고, 조회 영역을 A, B 두 영역으로 나눠서 생각해보았다.

 

  • A 영역: C 테이블
  • B 영역: A 테이블, E 테이블, F 테이블

즉 A 영역 같은 경우 일자에 따른 경기 일정만 가져오면 되므로 C 테이블만 조회하면 되고, B 영역의 경우 협회에 등록된 선수 명단(A & E)에 추가적으로 출전 선수 정보가 필요하므로 F 테이블을 걸어주어야 하지 않을까 생각했다. 그런데 이렇게 생각하니 선택한 경기에 따라 출전 선수가 바뀌지 않는 것 같아 아래와 같이 변경했다.

 

  • A 영역: C 테이블, F 테이블
  • B 영역: A 테이블, E 테이블

즉 A 영역에서 게임 목록과 각 게임에 대한 출전 선수 정보를 함께 담아와 경기 선택 시 자바스크립트 코드를 통해 출전선수에 대해 체크를 해주는 식이었다. 간략하게 A 영역 조회 쿼리를 써보자면 아래와 비슷하다.

 

SELECT C.게임일련번호
     , C.게임일자
     , LISTAGG(F.선수일련번호, ',') AS 선수일련번호
  FROM 게임 C
  LEFT OUTER JOIN 출전선수 F
    ON C.게임일련번호 = F.게임일련번호
 WHERE C.게임일자     = #{게임일자}
 GROUP BY C.게임일련번호
        , C.게임일자

 

정리하자면 부모 테이블에 그룹별로 해당하는 자식 테이블의 정보를 함께 조회[3]해올 때 LISTAGG 함수를 사용할 수 있다.

 

_____

1. LISTAGG 외에 오라클 버전에 따라 Group by에서 문자열 합치는 방법이 다르다.

2. 당연히 K리그 경기 일정을 선택할 때마다 서버와 통신하는 것은 고려하지 않았다. 일단 조회 후에는 모든 처리를 화면에서 할 수 있는 방법을 고민했다.

3. 흔히 OUTER JOIN을 생각할 때 조회되는 행의 수는 기준 테이블로 고정일 거라고 착각한다. 하지만 이 예에서처럼 기준 테이블이 부모 테이블인 경우 뻥튀기가 발생할 수 있기에 GROUP BY로 묶어주어야 한다. 채규병님의 다음 글(LEFT OUTER JOIN 시 주의할 점)을 참고하자.

 

_____

참고자료

 

'공부 > Database' 카테고리의 다른 글

조회 성능  (0) 2024.11.05
Database 경험  (0) 2024.11.05
JOIN과 Sub-Query의 차이  (0) 2021.04.17
서브쿼리 사용 예시  (0) 2020.12.12

댓글