CS-STUDY/데이터베이스

[토막 지식] Group by

HwangJerry 2023. 10. 15. 15:25

SQL을 통해 테이블에서 데이터를 일반적으로 조회할 때에는 필요하지 않지만,

만약 count(), avg(), sum()과 같은 집계 함수를 특정 기준으로 조회하도록 사용하기 위해서는 group by가 반드시 필요하다.

대표적인 집계함수
1. count(attr or *) : 특정 애트리뷰트 또는 전체 튜플(*)의 개수를 세어줌
2. avg(attr) : 특정 애트리뷰트의 평균을 내어줌
3. min(attr) : 특정 애트리뷰트의 최솟값을 반환함
4. max(attr) : 특정 애트리뷰트의 최댓값을 반환함
5. sum(attr) : 특정 애트리뷰트의 총 합을 반환함.

Group by

가령, 근로자의 전체 수를 구하는 sql은 select count(*) from employee; 과 같이 전체 테이블에 대하여 single value로 조회가 가능하다.

 

하지만 만약에 각 부서별 근로자의 숫자를 구하고 싶다면 어떻게 해야 할까? select dname, count(*) from employee; 와 같이 실행하게 되면 not a single-group group function 이라는 에러를 뱉어낸다. count()와 같은 집계 함수는 별도로 지정하지 않으면 전체 테이블을 하나의 그룹으로 지정하여 계산하기 때문에, 각 튜플에 대한 값을 선택하는 dname과 병치하여 값을 출력할 수 없는 것이다.

 

이를 해결하기 위해 사용하는 것이 group by이다. 이를 어떻게 사용하는지 이해하기 위해 예시와 함께 진행해보자.

 

아래 employee 테이블에 대하여 예시를 진행할 것이다.

다음 SQL을 진행하면 어떤 결과가 나올까?

select dno, count(*), avg(salary)
from employee
group by dno
order by dno;

위 SQL을 간단히 설명하자면, 부서 코드별 근로자의 숫자를 count()로 구해주고, 각 부서별 임금 평균을 avg(salary)로 구해주었다. (정렬은 그냥 보기 좋으라고 했다.) 결과는 아래와 같이 나온다.

만약 group by를 설정하기 않으면 이렇게 집계함수를 특정 기준에 맞게 사용할 수 없다.

 

Having

여기에 더하여 group by 를 적용하기 전에 기본 테이블의 특정 튜플을 기준으로 조회하기 위해서  where 절을 건 상태로 group을 지은 뒤 집계를 할 수도 있지만,

 

group by와 집계 함수를 사용한 후 얻은 집계 결과 중에서 having 을 걸어서 집계 데이터 중 필요한 결과만을 필터링하여 조회할 수도 있다. 

 

사용법을 보면 어렵지 않다. 아래 SQL을 확인해보자.

select dno, count(*), avg(salary)
from employee
group by dno
having avg(salary) <= 40000
order by dno;

위 SQL은 집계된 결과 중에서 임금 평균이 4만원 이하인 데이터만을 확인하기 위해 입력한 SQL이라고 할 수 있다. 결과는 아래와 같이 나왔다.

 

언뜻 보면 where과 having이 둘 다 조건을 거는 것이라서 비슷하게 느껴질 수도 있겠지만, 위 설명에서도 언급했듯이 조건을 거는 대상이 상당히 다르기 때문에 이를 구분하여 적절하게 사용하는 것이 중요하다.

 

참고: https://kimsyoung.tistory.com/entry/SQL-GROUP-BY-%E4%B8%8A-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%8B%A4%EC%A0%9C-%EC%A0%81%EC%9A%A9-%EB%B0%A9%EB%B2%95

참고 : https://extbrain.tistory.com/56