GROUP BY 구를 사용하면 집계함수로 넘겨주었던 집합을 그룹으로 나눌 수 있습니다.
그룹화를 통해 집계함수의 활용 범위를 넓힐 수 있습니다.
GROUP BY로 그룹화
GROUP BY를 사용하면 특정 열을 그룹화시킬 수 있습니다.
SELECT 열명 FROM 테이블명 GROUP BY 열명;
현재 다음과 같은 테이블이 존재한다고 가정해봅시다.
해당 테이블의 name을 GROUP BY를 통해 그룹화 시켜보겠습니다.
SELECT name FROM product GROUP BY name;
DISTINCT를 지정했을 때 처럼 중복이 제거되어 검색된 것을 볼 수 있습니다.
GROUP BY 구에 열을 지정하여 그룹화하면 지정된 열의 값이 같은 행이 하나의 그룹으로 묶입니다.
DISTINCT와 GROUP BY의 차이
DISTINCT와 GROUP BY 둘다 중복을 제거한다는 공통점이 있습니다.
하지만 GROUP BY의 경우 집계함수와 함께 사용할 경우 그룹화된 각각의 그룹이 인수로 넘겨집니다.
다음은 name열을 GROUP BY로 그룹화 시키고 집계함수를 사용한 예시입니다.
SELECT name, COUNT(name), SUM(quantity) FROM product GROUP BY name;
결과를 보면 name에 의해 그룹화되어 집계함수가 동작한 것을 볼 수 있습니다.
HAVING 구로 조건 지정
집계함수는 WHERE 구의 조건식에는 사용할 수 없습니다.
SELECT name, COUNT(name) FROM product WHERE COUNT(name)=1 GROUP BY name;
에러가 발생한 이유는 GROUP BY와 WHERE 구의 내부처리 순서와 관계가 있습니다.
WHERE 구로 행을 검색하는 처리가 GROUP BY로 그룹화하는 처리보다 먼저 처리되기 때문입니다.
내부처리 순서 WHERE 구 → GROUP BY 구 → SELECT 구 → ORDER BY 구
만약 집계한 결과에서 따로 조건에 맞는 값을 걸러내고 싶은 경우에는 HAVING구를 사용할 수 있습니다.
HAVING 구는 GROUP BY 구의 뒤에 기술하며 WHERE 구와 동일하게 조건식을 지정할 수 있습니다.
HAVING 구의 조건식에는 그룹별로 집계된 열의 값이나 집계함수의 계산결과를 전달하면 됩니다.
SELECT 열명 FROM 테이블명 GROUP BY 열명 HAVING 조건식
다음은 HAVING구를 사용한 예시입니다.
SELECT name, COUNT(name) FROM product GROUP BY name HAVING COUNT(name)=1;
HAVING을통해 name이 하나만 존재하는 열만 가져온 것을 볼 수 있습니다.
다음은 HAVING구의 내부처리 순서입니다.
WHERE 구 -> GROUP BY 구 -> HAVING 구 -> SELECT 구 -> ORDER BY 구
HAVING 구도 WHERE구와 마찬가지로 SELECT 보다 먼저 처리되므로 별명은 사용할 수 없습니다.
단 특정 데이터 베이스의 경우 별명을 사용할 수 있습니다. (ex : MySQL)
다음 명령은 처리순서 때문에 에러가 발생해야 하지만 MySQL에서 실제로 실행해보면 정상적으로 실행되는 것을 볼 수 있습니다.
SELECT name AS n, COUNT(name) AS cn FROM product
GROUP BY n HAVING cn = 1;
복수열의 그룹화
GROUP BY에 지정한 열 이외의 열은 집계함수를 사용하지 않은 채 SELECT구에 지정해서는 안됩니다.
예를 들어 다음과 같은 SQL이 있다고 가정해봅시다.
SELECT id, name, quantity FROM product GROUP BY name;
위의 SQL에서 name은 GROUP BY를 통해 지정되었지만 id와 quantity는 지정되어 있지 않은 상태입니다.
이 경우 그룹화된 값 중에서 어떤 값을 출력해야할지 SQL이 판단하지 못해 에러가 발생하게 됩니다.
실행해보면 다음과 같이 에러가 발생합니다.
다음과 같이 SELECT 구에서 어떤 값을 출력할지 집계함수를 통해 지정하면 출력할 수 있습니다.
SELECT MIN(id), name, SUM(quantity) FROM product GROUP BY name;
물론, 다음과 같이 GROUP BY에 지정해도 사용할 수 있습니다.
SELECT id, name, quantity FROM product GROUP BY id, name, quantity;
결과값 정렬
GROUP BY로 그룹화해도 실행결과 순서를 정렬할 수는 없습니다.
데이터베이스 내부 처리에서 같은 값을 그룹으로 나누는 과정에서 순서가 서로 바뀌는 부작용이 일어날 수도 있습니다.
하지만 이는 데이터베이스 내부처리의 문제로 데이터베이스 제품에 따라 다릅니다.
확실한 것은 GROUP BY 지정을 해도 정렬되지는 않는다는 점입니다.
GROUP BY 한 값을 정렬하기 위해서는 추가적으로 ORDER BY 를 사용해야 합니다.
다음은 ORDER BY를 사용해서 GROUP BY 결과를 정렬하는 SQL입니다.
SELECT name, COUNT(name), SUM(quantity) FROM product
GROUP BY name ORDER BY SUM(quantity) DESC;
정리
- GROUP BY를 사용하여 특정 열을 그룹화시킬 수 있습니다.
- GROUP BY로 그룹화한 열을 집계함수에 인수로 전달할 경우 그룹화된 단위로 집계됩니다.
- GROUP BY를 사용할때 조건식에 만족하는 값을 걸러내고 싶은 경우 HAVING을 사용할 수 있습니다. (WHERE은 동작순서상 GROUP BY 보다 빨리 실행)
- GROUP BY를 사용할 경우 GROUP BY의 지정하지 않은 열이나 집계함수를 사용하지 않은 열을 SELECT에 지정할 경우 에러가 발생합니다.
- GROUP BY의 결과값을 정렬하고 싶을 경우 ORDER BY를 사용하여 정렬할 수 있습니다.
'CS > DataBase' 카테고리의 다른 글
데이터베이스 첫걸음 정리 - 24장. 상관 서브쿼리 (0) | 2022.09.24 |
---|---|
데이터베이스 첫걸음 정리 - 23장. 서브쿼리 (1) | 2022.09.21 |
데이터베이스 첫걸음 정리 - 21장. COUNT 이외의 집계함수 (0) | 2022.09.17 |
데이터베이스 첫걸음 정리 - 20장. 행 개수 구하기 - COUNT (0) | 2022.09.14 |
데이터베이스 첫걸음 정리 - 19장. 물리삭제와 논리삭제 (0) | 2022.09.11 |