지지 On Air

2-1-5. GROUP BY, HAVING절 본문

개발/SQL [SQLD&SQLP]

2-1-5. GROUP BY, HAVING절

슈스 지지 2022. 7. 27. 20:29
반응형

 


저는 SQL을 기초 공부 없이 신입때 회사 업무를 맡게 되면서 접하게 되었는데요,
다른부분 보다도 GROUP BY 나 HAVING 이 좀 낯설게 느껴지더라구요 ㅎㅎ 구글링 해봤던 기억이 납니다 ㅎㅎ
그 기억을 살려서! 최대한 쉽게 책 내용 풀어보겠습니다 :)


 

과목 II. SQL 기본과 활용
- 제1장 SQL 기본
> 제5절 GROUP BY, HAVING 절

 

1. 집계함수

집계함수(Aggregate Function)의 특성은 다음과 같다.
- 여러 행들의 그룹이 모여 그룹당 단 하나의 결과를 돌려주는 함수
- GROUP BY 절은 행들을 소그룹화 한다.
- SELECT절, HAVING절, ORDER BY 절에 사용할 수 있다.

집계함수 사용목적
COUNT(*) NULL 값을 포함한 행의 수를 출력한다
COUNT(표현식) 표현식의 값이 NULL값인 것을 제외한 행 수를 출력한다
SUM([DISTINCT | ALL] 표현식) 표현식의 NULL값을 제외한 합계를 출력한다
AVG([DISTINCT | ALL] 표현식) 표현식의 NULL값을 제외한 평균을 출력한다
MAX([DISTINCT | ALL] 표현식) 표현식의 최댓값을 출력한다
MIN([DISTINCT | ALL] 표현식) 표현식의 최소값을 표현한다
STDDEV([DISTINCT | ALL] 표현식) 표현식의 표준편차를 출력한다
VARIANCE/VAR([DISTINCT | ALL] 표현식) 표현식의 분산을 출력한다
기타 통계 함수 벤터별로 다양한 통계식을 제공한다


일반적으로 집계함수는 GROUP BY 절과 같이 사용되지만 테이블 전체가 하나의 그룹이 되는 경우에는 GROUP BY 절 없이 단독으로도 사용 가능 하다. 예를들면 다음과 같다.

SELECT COUNT(*) AS 전체행수, COUNT(HEIGHT) AS 키건수, MAX(HEIGHT) AS 최대키, MIN(HEIGHT) AS 최소키, ROUND(AVG(HEIGHT),2) AS 평균키
FROM PLAYER;


결과는 다음과 같이 나올것이다.

전체행수 키건수 최대키 최소키 평균키
480 447 199 165 179.31

 

2. GROUP BY 절

WHERE절을 통해 조건에 맞는 데이터를 조회했지만, 테이블에 1차적으로 존재하는 데이터 이외의 정보 (예를 들면 팀별로 선수가 몇명인지, 선수들의 평균키와 몸무게가 어떻게 되는지 등등) 즉 2차 가공 정보도 필요하다.
GROUP BY 절은 SQL문에ㅔ서 FROMㅈㄹ과 WHERE 절 뒤에 오며 데이터들을 작은 그룹으로 분류해 소그룹에 대한 항목별로 통계 정보를 얻을 때 추가로 사용된다.
기본 구조는 다음과 같다.

SELECT [DISTINCT] 칼럼명 [ALIAS명]
FROM 테이블명
[WHERE 조건식]
[GROUP BY 칼럼이나 표현식]
[HAVING 그룹조건식];

 

GROUP BY 절과 HAVING 절을 다음과 같은 특성을 가진다.
- GROUP BY 절을 통해 소그룹별 기준을 정한후, SELECT 절에 집계함수를 사용한다
- 집계함수의 통계정보는 NULL값을 가진 행을 제외하고 수행한다
- GROUP BY 절에서는 SELECT절과 달리 ALIAS를 사용할 수 없다
- 집계함수는 WHERE절에는 올수없다 (WHERE절이 먼저 수행됨)
- WHERE절은 전체 데이터를 GROUP으로 나누기 전에 행들을 미리 제거한다
- HAVING 절은 GROUP BY 절의 기준항목이나 소그룹의 집계함수를 이용한 조건을 표시할 수 있다.
- GROUP BY절에 의한 소그룹별로 만들어진 집계데이터중, HAVING절에서 제한 조건을 두어 조건을 만족하는 내용만 출력한다
- HAVING절은 일반적으로 GROUP BY 절 뒤에 위치한다

일반적으로 쉽게 범할수 있는 오류가 나는 쿼리문을 알아보자.

SELECT POSIION AS 포지션, AVG (HEIGHT) AS 평균키
FROM PLAYER;

GROUP BY 절에서 그룹 단위를 표시해 주어야 SELECT 절에서 그룹 단위의 칼럼과 집계함수를 사용할 수 있기 때문에, 위의 쿼리문은 오류가 날 것이다. 

 

또한 다음 쿼리문에서도 오류가 날 것이다.

SELECT POSITION AS 포지션, AVG (HEIGHT) AS 평균키
FROM PLAYER
GROUP BY 포지션;

위에서 설명했듯, GROUP BY 에서는 ALIAS명을 사용할수 없다. 따라서 마지막 문장 GROUP BY 포지션 부분에서 에러가 날 것이다.

 

포지션별로 평균키, 인원수, 키대상 인원수, 최대키를 출력하기 위해서는 다음과 같이 SQL문을 작성하면 된다.

SELECT POSITION AS 포지션, COUNT (*) AS 인원수, COUNT (HEIGHT) AS 키대상, MAX (HEIGHT) AS 최대키
FROM PLAYER
GROUP BY POSITION;

 

결과는 다음과 같을것이다.

포지션 인원수 키대상 최대키
  3 0  
GK 43 43 196
DF 172 142 190
FW 100 100 194
MF 162 162 189

최대키를 구할때 키 값이 NULL인 경우는 계산 대상에서 제외된다.

 

 

3. HAVING절

오류가 발생하는 SQL문 먼저 살펴보자.

SELECT POSITION AS 포지션, ROUND(AVG(HEIGHT),2) AS 평균키
FROM PLAYER
WHERE AVG(HEIGHT) >= 180
GROUP BY POSITION;

3행에서 오류가 나게된다. 에러 메세지는 '그룹함수는 허가되지 않는다' 라고 출력될것이다.

WHERE절에는 AVG()라는 집계함수를 사용할 수 없기 때문이다.

WHERE절의 조건에 맞는 행이 GROUP BY 절의 대상이 된다. 그런 다음, 결과 집합의 행에 HAVING 조건절이 적용된다.

결과적으로 HAVING 절의 조건을 만족하는 내용을 출력한다.

HAVING절은 WHERE절과 비슷하지만, 그룹을 나타내는 결과 집합의 행에 조건이 적용된다는 점에서 차이가 있다.

 

SELECT POSITION AS 포지션, ROUND(AVG(HEIGHT),2) AS 평균키
FROM PLAYER
GROUP BY POSITION
HAVING AVG(HEIGHT) >= 180;

이렇게 작성해야 올바른 결과를 출력할수 있다. 결과는 다음과 같을 것이다.

포지션 평균키
GK 186.26
DF 180.21

 

GROUP BY절과 HAVING절의 순서를 바꾸어서 수행하더라도 문법 에러가 없고 결과물도 동일한 결과를 출력한다.

단, SQL Server에서는 문법오류가 발생하므로, GROUP BY 절과 HAVING절의 순서를 지키는 것을 권고한다.

 

 


이래저래 바빠서 포스팅을 너무 오랜만에 올리는것 같습니다 ㅠㅠ

이번 절에서는 GROUP BY와 HAVING절을 다루었습니다.

실제로 GROUP BY절과 HAVING절은 실무에서 빼놓을수 없는 부분입니다. 

작성되어있는 쿼리문(프로시저)를 분석하고 필요에따라 수정하고 활용하기 위해서는 한줄한줄 차근차근 이해하는 수 밖에 없습니다. 이번 절에서도 다루었듯 기초적인 구조와 활용방법을 안다면 분석하기 더 쉬워지겠죠 ^^

차후에 길게 작성된 프로시저를 분석하는것도 재밌는 포스팅이 될 수 있을것 같네요 ㅎㅎ

 

구독과 하트, 댓글은 큰 힘이 됩니다. 읽어주셔서 감사합니다 :)

 


본 포스팅은 '한국데이터산업진흥원' 에서 발행한 'SQL 전문가 가이드' 를 참고/인용 하였음을 밝힙니다.
반응형

'개발 > SQL [SQLD&SQLP]' 카테고리의 다른 글

2-1-7. 조인(JOIN) [ SQL 가이드 ]  (15) 2022.07.29
2-1-6. ORDER BY 절  (12) 2022.07.28
2-1-4. WHERE절  (12) 2022.07.23
2-1-3. 함수(2)  (2) 2022.07.22
2-1-3. 함수(1)  (4) 2022.07.21
Comments