DataBase/MYSQL

[MYSQL] 기본 문법(8) - GROUP BY 와 HAVING

민졈 2022. 10. 25. 15:36

 

 

 

 

이번 시간에는 GROUP BY에 대해 알아보도록 하겠습니다.

 

 

 

 

GROUP BY 절은 데이터들을 원하는 그룹으로 그룹화 할 수 있습니다.

 

GROUP BY 절은 주로 집계 함수와 같이 사용되곤 합니다.

 

평균 값을 구하거나, 최대/ 최소 값을 구하는 등

 

AVG, MIN, MAX, SUM, COUNT 등의 집계 함수와 말이죠.

 

사용하는 위치는 FROM 뒤에 WHERE 처럼 사용해주면 되는데요

 

집계함수와 함께 사용되는 상수는 GROUP BY 절에 추가하지 않아도 됩니다.

 

 

 

 

 

여러 예제들과 함께 GROUP BY의 사용법에 대해 알아보도록 하겠습니다.

 

 

SELECT '2022년' year, deptno 부서번호, COUNT(*) 사원수
     FROM emp
   GROUP BY deptno
   ORDER BY COUNT(*);

YEAR 부서번호 사원수
2022년 11 32
2022년 12 20
2022년 13 15
2022년 14 22

위의 쿼리는 부서별 사원을 조회하는 쿼리인데요

 

앞서 이야기 했던 것처럼 위치는 FROM 절 뒤에 있고

 

부서별 사원을 조회하려고 했기 때문에

 

GROUP BY 절에 부서번호인 deptno를 사용했습니다.

 

결과를 보시면 부서번호에 따라서 사원수가 나온 것을 알 수 있죠.

 

여기서 COUNT에 *를 쓰는 것은 모든 사원수를 조회하겠다는 것입니다. 특정 컬럼의 수를 세고자 한다면 * 대신 컬럼 명을 사용할 수도 있습니다. 이 둘의 차이점은 NULL 값을 포함하는 여부인데요 *는 NULL 값을 포함한 행의 갯수를 반환하고 컬럼 명을 사용하면 NULL 값을 제외한 행의 갯수를 반환합니다.

 

 

 

 

SELECT deptno 부서번호, COUNT(*) 사원수
            ,ROUND(AVG(sal)) "평균 급여"
            ,MAX(sal) "최고 급여액" 
            ,ROUND(SUM(sal)) "급여 합계"
     FROM emp
   GROUP BY deptno;
   ORDER BY deptno;

부서번호 사원수 급여평균 최고 급여액 급여합계
11 32 4000 4200 130000
12 20 2550 2700 53000
13 15 2800 3000 48000
14 22 3200 3500 75400

 

위에서 평균 급여와 최고 급여액, 급여 합계를 구하는 쿼리를 작성했습니다.

 

맨 처음 이야기 했듯이 집계 함수들을 사용하지만

 

GROUP BY 절에는 집계 함수를 사용한 컬럼이 아닌

 

기준으로 묶기 위한 컬럼인 부서번호 DETPNO를 사용했습니다.

 

 

 

 

 

이런 GROUP BY 절에는 WHERE 와 같이 조건을 줄 수 있는 HAVING을 같이 쓰기도 합니다.

 

 

 

아래의 예제는 프로그래머스에 있는 GROUP BY 예제 중 하나입

니다.

 

 

GROUP BY 예제 > 동명 동물 수 찾기

ANIMAL_INS 테이블은 동물 보호소에 들어온 동물의 정보를 담은 테이블입니다. 
ANIMAL_INS 테이블 구조는 다음과 같으며, ANIMAL_ID, ANIMAL_TYPE, DATETIME, INTAKE_CONDITION, NAME, SEX_UPON_INTAKE 는 각각 동물의 아이디, 생물 종, 보호 시작일, 보호 시작 시 상태, 이름, 성별 및 중성화 여부를 나타냅니다.

NAME TYPE
ANIMAL_ID VARCHAR(N)
ANIMAL_TYPE VARCHAR(N)
DATETIME DATETIME
INTAKE_CONDITION VARCHAR(N)
NAME VARCHAR(N)
SEX_UPON_INTAKE  VARCHAR(N)


문제 ) 동물 보호소에 들어온 동물 이름 중 두 번 이상 쓰인 이름과 해당 이름이 쓰인 횟수를 조회하는 SQL문을 작성해주세요. 이때 결과는 이름이 없는 동물은 집계에서 제외하며, 결과는 이름 순으로 조회해주세요.

 

우선 조회하고자 하는 것은 두 번 이상 쓰인 이름과 이름이 쓰인 횟수이기 때문에

   SELECT name, count(name) as count

select 문에 조회하고자 하는 컬럼을 작성합니다.

 

ANIMAL_INS 라는 테이블에서 가져오기 때문에

FROM 절은 아래와 같이 작성해주었구요

   FROM animal_ins

 

 

이름을 조회하고 그 이름이 쓰인 횟수를

같이 조회하기 때문에 기준이 되는 컬럼은 NAME 이 됩니다.

  GROUP BY name

때문에 GROUP BY 에 사용해야 하는 컬럼 역시 NAME입니다.

 

 

문제의 조건에 두 번 이상 쓰인 이름이라고 했기 때문에

HAVING 절에 조건을 작성하면 됩니다.

이름을 COUNT 해서 2보다 크거나 같은 데이터를 가져오면 되겠죠.

   HAVING count(name) >= 2

 

마지막으로 정렬 기준까지 작성해주면 간단하게 쿼리를 완성할 수 있습니다.

   ORDER BY name;

 

완성된 쿼리문

SELECT NAME
              , COUNT(NAME) AS COUNT
FROM ANIMAL_INS
GROUP BY NAME
HAVING COUNT(NAME) >= 2
ORDER BY NAME;

 

 

이렇게 GROUP BY, 이와 함께 사용되는 HAVING에 대해 알아봤습니다.

 

다음에는 JOIN 문에 대해 알아보도록 하겠습니다.