포스트

SQLD: GROUP BY, HAVING, ORDER BY

GROUP BY, HAVING 절

GROUP BY 문법을 이용하면 집계를 구할 수 있다. 여기서 집계라 함은 합계를 구한다거나, 개수, 최대값, 평균값 등 보다 의미 있는 정보를 구하는 것을 일컫는다.

1
2
3
SELECT 소속반, COUNT(*) AS 반별인원수
FROM 수강생정보
GROUP BY 소속반; 

image

GROUP BY는 특정 컬럼을 기준으로 튜플(행)을 그룹화하여(묶어서) 각각 단일행으로 표기한다.

GROUP BY는 실제로 툴력되는 행이 감소한다. 즉, 입력할 수 있는 칼럽이 제한된다. (HAVING, ORDER BY, SELECT에서 제한)

집계함수

집계함수는 다중행 함수라고도 부르는데, 여러 행을 입력 받아 행 개수를 집계하여 하나의 결과로 출력한다는 말이다.

COUNT

COUNT(expr)

  • 그룹핑할 컬럼 기준으로 행의 개수를 출력한다.
  • 다른 집계함수와 달리 *을 expr에 쓸 수 있다.
  • 모든 자료형에 이용 가능하다.

COUNT(*)은 그룹별 NULL을 포함한 행의 개수를 출력한다.
COUNT(컬럼)은 해당 컬럼에서 NULL값을 제외하고 행의 개수를 출력한다.

아래는 학생들의 과목별 성적을 기입한 테이블이다.

image

COUNT(성적)을 사용하면 6번 학생은 성적에 NULL값이 있기 때문에 0으로 출력된다.

image

COUNT(*)을 사용하면 NULL값을 포함하여 인스턴스의 개수를 출력한다.

image

MAX / MIN

MAX(expr), MIN(expr)

  • 그룹 기준으로 입력한 expr에 대해 최대값이나 최소값을 출력한다.
  • NULL 데이터는 무시한다. (모두 NULL이면 NULL출력)
  • 모든 자료형에 이용 가능하다. ( 숫자: 1 < 2문자: ㄱ < ㅎ날짜: 어제 < 오늘 )

위의 성적표 테이블을 참고하여 MAX 함수를 사용해보면 다음과 같다:

1
2
3
SELECT 학생ID, MAX(성적)
FROM 성적표
GROUP BY 헉생ID;

출력:
image

MIN은 반대의 개념이다.

AVG

AVG(expr)

  • 그룹 기준으로 입력한 expr에 대해 평균을 출력한다.
  • NULL 데이터는 무시한다. (모두 NULL이면 NULL출력)
  • 숫자형에만 이용 가능하다.

위의 성적표 테이블을 참고하여 AVG 함수를 사용해보면 다음과 같다:

1
2
3
SELECT 학생ID, AVG(성적)
FROM 성적표
GROUP BY 헉생ID;

출력:
image

SUM

SUM(expr)

  • 그룹 기준으로 입력한 expr에 대해 합계값을 출력한다.
  • NULL 데이터는 무시한다. (모두 NULL이면 NULL출력)
  • 숫자형에만 이용 가능하다.

위의 성적표 테이블을 참고하여 AVG 함수를 사용해보면 다음과 같다:

1
2
3
SELECT 학생ID, SUM(성적)
FROM 성적표
GROUP BY 헉생ID;

출력:
image


HAVING

HAVING 문법은 집계가 완료된 대상을 필터링 하는 문법이다.

1
2
3
4
SELECT 학생ID, ROUND(AVG(성적), 1) AS 평균성적
FROM 성적표
GROUP BY 학생ID
HAVING AVG(성적) <= 75;

HAVING은 집계함수에 대해 조건을 줄 수 있다.
WHERE절에서는 집계함수를 사용할 수 없다.

그렇기 때문에 다음의 경우에는 오류가 뜬다.

1
2
3
4
SELECT 학생ID, ROUND(AVG(성적), 1) AS 평균성적
FROM 성적표
WHERE AVG(성적) <= 75
GROUP BY 학생ID;

WHERE절에서는 집계함수를 사용하지 못하는 이유는, WHERE절은 GROUP BY 보다 먼저 실행이 되기 떄문이다. 집계함수는 GROUP BY가 먼저 되어야 사용이 가능하다. AVG(성적)은 집계함수이기 때문에 GROUP BY가 되지 않은 시점에서는 사용하지 못한다.

순서:

  1. FROM
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. SELECT
  6. ORDER BY
1
2
3
4
5
SELECT 학생ID, AVG(성적) AS 수학제외평균
FROM 성적표
WHERE 과목 != '수학'
GROUP BY 학생ID
HAVING AVG(성적) <= 75; 

WHERE절과 HAVING 문법은 둘 다 필터링 용도이지만, 집계함수의 사용여부에 따라 사용이 갈린다.

ORDER BY

ORDER BY는 특정 컬럼을 기준으로 데이터를 오름차순/내림차순 정렬한다.

문제: TB_PRD 테이블을 PRD_AMT 기준으로 오름차순으로 정렬하여 출력해주세요.

1
2
3
SELECT * 
FROM TB_PRD
ORDER BY PRD_AMT;

문제1: TB_PRD 테이블을 PRD_AMT 기준으로 내림차순으로 정렬하여 출력해주세요.

1
2
3
SELECT * 
FROM TB_PRD
ORDER BY PRD_AMT DESC;

descend(내림차)에서 DESC를 따와서 내림차순으로 정렬할 수 있다.

문제2: TB_PRD 테이블을 PRD_TYPE 별로 오름차순 정렬하되, 같은 타입일 경우 PRD_AMT 순으로 내림차순으로 정렬하여 출력해주세요.

1
2
3
SELECT *
FROM TB_PRD
ORDER BY PRD_TYPE, PRD_AMT DESC;

-> 상품 타입을 기준으로 정렬, 이후에 추가적으로 PRD_AMT 기준으로 정렬. 이와 같이 여러 컬럼을 사용해도 된다.

image

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.