SELECT – GROUP BY (SQLite3)

이번 글에서는 SELECT 구문 내에서 GROUP BY 절에 대해서 살펴보자. GROUP BY는 결과 행들을 특정한 하나 혹은 그 이상의 칼럼에 의한 그룹으로 묶어서 그룹을 요약하는 몇 가지 행들로 표현되도록 하는 것이다. 보통 MIN, MAX, SUM, AVG, COUNT 등과 같은 집합 함수와 같이 함께 사용된다. GROUP BY를 적용하는 주요 쿼리 구문의 형식은 다음과 같다.

  • SELECT column1, aggregate_func(column1)
  • FROM _table
  • GROUP BY column1, column2, …. ;

다음의 예는 노래 정보 테이블에서 각 앨범당 수록곡의 개수를 산출하는 쿼리이다.

SELECT albumid, COUNT(trackid)
FROM tracks
GROUP BY albumid;

이 쿼리는 다음과 같이 해석된다.

  1. albumid가 같은 행들은 모두 각각 하나의 그룹으로 취급된다.
  2. 그룹으로 나눠진 대상에 대해서 각 그룹의 albumid와 I의 개수를 리턴한다.

집합 함수로 분류되는 몇몇 함수들은 각 그룹마다 그 그룹에 속해있는 행들에 대해서 반복적용된다.

HAVING 절

having 절을 그룹에 대한 필터링을 수행하는 조건을 추가할 수 있는 절이다. 그룹에 대한 조건이므로 대체로 조건은 aggregate 함수와 같이 쓰인다. 특정 칼럼의 합계나 평균, 최대/최소 및 개수가 어떻다는 식으로 조건을 걸 수 있는 셈이다.

조금 전 작성했던 예제를 GROUP BY와 HAVING을 끼얹은 형태로 살짝 변경해보자.

SELECT albumid, COUNT(trackid)
FROM tracks
GROUP BY albumid
HAVING count(albumid) BETWEEN 18 AND 20
ORDER BY albumid;

위 쿼리는 다음과 같이 동작할 것이다

  1. albumid 값으로 그룹지어 그 행이 18~20 범위에 있는 앨범에 대해서
  2. albumid와 trackid의 개수를
  3. albumid 순으로 출력한다.

즉 수록곡이 18~20개 인 앨범을 출력하라는 쿼리가 된다.

HAVING vs WHERE

그렇다면 GROUP BY가 사용된 쿼리에 WHERE 대신에 HAVING을 쓰면 되는 것이냐? 그것은 아니다. 하나의 쿼리에 HAVING 절과 WHERE 절은 양립할 수 있다. WHERE 절은 각각의 ROW를 필터링하는 조건이 된다. GROUP BYWHERE절에 의해서 필터링된 결과에 대해서 주어진 칼럼으로 데이터를 그룹핑한다. 이후 각각의 그룹에 대해서 특정한 조건으로 다시 필터링할 때 HAVING을 사용할 수 있다.