오경석의 개발노트

Oracle_GROUP BY, HAVING 절 본문

프로그래밍 언어/Oracle

Oracle_GROUP BY, HAVING 절

OHSAYU 2023. 11. 10. 18:37

1. GROUP BY 절

    WHERE 절을 통해 조건에 맞는 데이터를 조회했지만 테이블에 1차적으로 존재하는 데이터 이외의 정보, 예를 들면 각 팀별로 선수가 몇 명인지, 선수들의 평균 신장과 몸무게가 얼마나 되는지, 또는 각 팀에서 가장 큰 키의 선수가 누구인지 등의 2차 가공 정보도 필요하다. GROUP BY 절은 SQL 문에서 FROM 절과 WHERE 절 뒤에 오며, 데이터들을 작은 그룹으로 분류하여 소그룹에 대한 항목별로 통계 정보를 얻을 때 추가로 사용된다.

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

 

GROUP BY 절과 HAVING 절은 다음과 같은 특성을 가진다.

- GROUP BY 절을 통해 소그룹별 기준을 정한 후, SELECT 절에 집계 함수를 사용

- 집계 함수의 통계 정보는 NULL 값을 가진 행을 제외하고 수행

- GROUP BY 절에서는 SELECT 절과는 달리 ALIAS 명을 사용할 수 없다.

- 집계 함수는 WHERE 절에는 올 수 없다. (집계 함수를 사용할 수 있는 GROUP BY 절보다 WHERE 절이 먼저 수행)

- WHERE 절은 전체 데이터를 GROUP으로 나누기 전에 행들을 미리 제거

- HAVING 절은 GROUP BY 절의 기준 항목이나 소그룹의 집계 함수를 이용한 조건을 표시

- GROUP BY 절에 의한 소그룹별로 만들어진 집계 데이터 중, HAVING 절에서 제한 조건을 두어 조건을 만족하는 내용만 출력

- HAVING 절은 일반적으로 GROUP BY 절 뒤에 위치

 

 

[예제] 포지션별 최대키, 최소키, 평균키를 출력한다. 
SELECT
    POSITION           AS 포지션,
    COUNT(*)           AS 인원수,
    COUNT(HEIGHT)      AS 키대상,
    MAX(HEIGHT)        AS 최대키,
    MIN(HEIGHT)        AS 최소키,
    ROUND(AVG(HEIGHT)) AS 평균키
FROM PLAYER
GROUP BY POSITION;

 

 

2. HAVING 절

    HAVING 절은 WHERE 절과 비슷하지만 그룹을 나타내는 결과 집합의 행에 조건이 적용된다는 점에서 차이가 있다. WHERE 절은 GROUP BY 절 이전에, HAVING 절은 이후에 수행되므로 GROUP BY에 의한 집계함수는 WHERE 절이 아닌 HAVING 절에 조건을 표현해야한다.

 

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

 

 

[예제] K-리그의 선수들 중 삼성블루윙즈(K02)와 FC서울(K09)의 인원수는 얼마인가.
SELECT
    TEAM_ID  AS 팀명,
    COUNT(*) AS 인원수
FROM PLAYER
WHERE TEAM_ID IN('K02', 'K09')
GROUP BY TEAM_ID;

    GROUP BY 소그룹의 데이터 중 일부만 필요한 경우, GROUP BY 연산 전 WHERE 절에서 조건을 적용하여 필요한 데이터만 추출하여 GROUP BY 연산을 하는 방법과, GROUP BY 연산 후 HAVING 절에서 필요한 데이터만 필터링 하는 두 가지 방법을 사용할 수 있다. 같은 실행 결과를 얻는 두 가지 방법 중 HAVING 절에서 TEAM_ID 같은 GROUP BY 기준 칼럼에 대한 조건을 추가할 수도 있으나, 가능하면 WHERE 절에서 조건절을 적용하여 GROUP BY의 계산 대상을 줄이는 것이 효율적인 자원 사용 측면에서 바람직하다.

 

 

[예제] 팀별 포지션별 FW, MF, DF, GK 포지션의 인원수와 팀별 전체 인원수를 구하는 SQL 문장을 작성한다. 데이터가 없는 경우는 0으로 표시한다.
SELECT 
    TEAM_ID, 
    NVL(SUM(CASE WHEN POSITION = 'FW' THEN 1 END), 0) FW, 
    NVL(SUM(CASE WHEN POSITION = 'MF' THEN 1 END), 0) MF, 
    NVL(SUM(CASE WHEN POSITION = 'DF' THEN 1 END), 0) DF, 
    NVL(SUM(CASE WHEN POSITION = 'GK' THEN 1 END), 0) GK, 
    COUNT(*) SUM 
FROM PLAYER 
GROUP BY TEAM_ID;

 

 

출처 : SQL 전문가 가이드

'프로그래밍 언어 > Oracle' 카테고리의 다른 글

Oracle_SELECT 문장 실행 순서  (1) 2023.11.12
Oracle_ORDER BY 절  (0) 2023.11.11
Oracle_집계함수  (0) 2023.11.10
Oracle_WHERE 절  (0) 2023.11.10
Oracle_NULL 함수  (0) 2023.11.09
Comments