[SQL] GROUP BY, HAVING 사용 방법

2022. 8. 12. 20:21데이터베이스/SQL

728x90

안녕하세요. 오늘은 GROUP BYHAVING 에 대해서 알아보겠습니다.

 

 

GROUP BY

GROUP BY는 컬럼값을 그룹화시킬 때 사용하는 함수로 주로 통계를 낼 때 사용합니다.

 

예를 들어

 

- 특정 컬럼의 합계값를 구할 때

- 특정 컬럼의 평균값을 구할 때

- 특정 컬럼의 최소값, 최대값을 구할 때

 

등등 그룹별 정보를 조회할 때 사용됩니다.

 

통계를 알아보기 전에 먼저 그룹화에 대해 알아보겠습니다.

 

그룹화란 쉽게 말해 중복된 컬럼값을 제거하고 하나만 표기한다 생각하면 됩니다.

 

설명을 돕기 위해 컬럼이 NAME, PRICE 두 개로 이루어진 가상테이블을 만들었습니다.

 

1
2
3
4
5
6
7
8
  WITH temp AS (
    SELECT 'apple' AS NAME, 1000 AS PRICE FROM dual UNION ALL
    SELECT 'apple' AS NAME, 2000 AS PRICE FROM dual UNION ALL
    SELECT 'banana' AS NAME, 3000 AS PRICE FROM dual UNION ALL
    SELECT 'orange' AS NAME, 4000 AS PRICE FROM dual UNION ALL
    SELECT 'grape' AS NAME, 5000 AS PRICE FROM dual
)
SELECT * FROM temp
cs

 

쿼리 결과값을 보면 apple 2개, banana 1개, orange 1개, grape 1개, 총 5개로 이루어졌습니다.

 

 

여기서 NAME 컬럼으로 그룹화를 시켜보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
  WITH temp AS (
    SELECT 'apple' AS NAME, 1000 AS PRICE FROM dual UNION ALL
    SELECT 'apple' AS NAME, 2000 AS PRICE FROM dual UNION ALL
    SELECT 'banana' AS NAME, 3000 AS PRICE FROM dual UNION ALL
    SELECT 'orange' AS NAME, 4000 AS PRICE FROM dual UNION ALL
    SELECT 'grape' AS NAME, 5000 AS PRICE FROM dual
)
SELECT 
       NAME 
  FROM temp
 GROUP BY NAME
cs

 

결과값을 보면 apple 1개, banana 1개, orange 1개, grape 1개 총 4개로 바뀌었습니다.

 

apple 이 그룹화된 것인데요.

 

이렇게 그룹화된 상태에서 서두에 말한 통계를 사용하겠다 할 땐 집계함수가 필요합니다.

 

자주 사용되는 집계함수의 종류를 먼저 알아볼게요.

 

집계함수 사용 용도
MAX 최대값
MIN 최소값
MEDIAN 중앙값
SUM 합계
AVG 평균
VARIANCE 분산(평균에서 떨어진 정도)
STDDEV 표준편차(평균과의 차액)
COUNT 결과값 수

 

사용 방식은 이와 같습니다.

 

집계함수(집계할 컬럼명)

 

위의 가상테이블을 예로 들어 만약 GROUP BY 로 묶인 데이터의 결과값 수를 구하고 싶어 COUNT 를 사용한다면

 

COUNT(NAME)

위와 같이 사용하면 됩니다.

 

 

쿼리와 결과값을 보면

1
2
3
4
5
6
7
8
9
10
11
12
  WITH temp AS (
    SELECT 'apple' AS NAME, 1000 AS PRICE FROM dual UNION ALL
    SELECT 'apple' AS NAME, 2000 AS PRICE FROM dual UNION ALL
    SELECT 'banana' AS NAME, 3000 AS PRICE FROM dual UNION ALL
    SELECT 'orange' AS NAME, 4000 AS PRICE FROM dual UNION ALL
    SELECT 'grape' AS NAME, 5000 AS PRICE FROM dual
)
SELECT 
       NAME
     , COUNT(NAME) AS FRUIT_COUNT   
  FROM temp
 GROUP BY NAME
cs

 

그룹으로 묶인 apple 만 2개가 카운트되고 나머지는 1개가 카운트된 걸 볼 수 있습니다.

 

이제 합계나 평균을 알아볼까요?

 

먼저 가상테이블을 만들 때 NAME 과 같이 PRICE 컬럼을 만들고 컬럼값은 정수로 주었습니다.

 

 PRICE 컬럼으로 가격의 합(SUM), 평균(AVG)를 나타낼 땐 이와 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  WITH temp AS (
    SELECT 'apple' AS NAME, 1000 AS PRICE FROM dual UNION ALL
    SELECT 'apple' AS NAME, 2000 AS PRICE FROM dual UNION ALL
    SELECT 'banana' AS NAME, 3000 AS PRICE FROM dual UNION ALL
    SELECT 'orange' AS NAME, 4000 AS PRICE FROM dual UNION ALL
    SELECT 'grape' AS NAME, 5000 AS PRICE FROM dual
)
SELECT 
       NAME
     , COUNT(NAME) AS FRUIT_COUNT   
     , SUM(PRICE) AS PRICE_SUM  
     , AVG(PRICE) AS PRICE_AVG   
  FROM temp
 GROUP BY NAME
cs

 

 

apple 의 경우 카운트된 갯수가 2개였고 각각 가격이 1000, 2000 이었습니다.

 

여기서 집계함수  SUM, AVG 를 사용하여

 

SUM은 합계인 3000

 

AVG는 평균인 1500

 

결과값이 나왔습니다.

 


HAVING

 

이제 HAVING 에 대해 알아보겠습니다.

 

HAVINGWHERE 절 처럼 특정 조건을 건다 생각하면 됩니다.

 

위와 같이 GROUP BY 로 묶인 데이터에서 합계(SUM)가 4000 이상인 데이터만 보고 싶다면

GROUP BY 다음에 HAVING 을 이용해 조건을 추가하면 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  WITH temp AS (
    SELECT 'apple' AS NAME, 1000 AS PRICE FROM dual UNION ALL
    SELECT 'apple' AS NAME, 2000 AS PRICE FROM dual UNION ALL
    SELECT 'banana' AS NAME, 3000 AS PRICE FROM dual UNION ALL
    SELECT 'orange' AS NAME, 4000 AS PRICE FROM dual UNION ALL
    SELECT 'grape' AS NAME, 5000 AS PRICE FROM dual
)
SELECT 
       NAME
     , COUNT(NAME) AS FRUIT_COUNT   
     , SUM(PRICE) AS PRICE_SUM  
     , AVG(PRICE) AS PRICE_AVG   
  FROM temp
 GROUP BY NAME
HAVING SUM(PRICE) >= 4000
cs

 

 

가격이 4000 이상인 orage, grape 만 조회된 걸 볼 수 있습니다.

 


이상으로 GROUP BYHAVING 에 대해 알아봤습니다.

 

잘못된 부분이나 부족한 부분은 피드백 주시면 감사하겠습니다.