SQL - DML의 GROUP BY 와 HAVING 사용법 - 23.11.20~21

songmin jeon·2023년 11월 20일
0

1. GROUP BY

특정 컬럼을 기준으로 그룹화

  SELECT 소속반, COUNT(소속반)
  FROM 수강생정보
  GROUP BY 소속반;


1.1. GROUP BY에 필요한 집계함수

집계함수만 별도로 사용 가능하나, 하나 이상의 인스턴스를 원한느 경우에는 SELECT절의 컬럼과 GROUP BY 의 컬럼이 동일하게 있어야 한다.

1.1.1. COUNT(col) (시험예상)

  • 그룹한 컬럼 기준으로 행의 개수를 출력
  • 다른 집계함수와 달리 col 자리에 * 사용 가능
  • 모든 자료형에 이용가능
  • (*) null을 포함
  • (col) null을 제외

1.1.2. MAX(col), MIN(col)

  • 그룹화된 컬럼을 기준으로 col의 최대 및 최소값을 출력
  • null 데이터는 무시(대신, 모두 null이면 null출력)
  • 모든 자료형에 이용가능

1.1.3.AVG(col)

  • 그룹 기준으로 입력한 col에 대해 평균 값을 출력
  • null 데이터는 무시(대신, 모두 null이면 null출력)
  • 숫자형에만 이용가능

1.1.4.SUM(col)

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

1.2. GROUP BY 실습문제 풀이

--실습 문제
--1. 성적표 테이블에서 학생별로 평균점수를 출력해주세요.
--이때 소수점 1자리 까지만 출력되도록 ROUND 함수도 활용해보세요.
--[ 힌트 : ROUND ( 평균을뽑은값 , 1 ) ]
  SELECT	학생ID, AVG(성적) AS 평균성적
  FROM	성적표
  GROUP BY 학생ID ;

--2. 직원 테이블에서 모든 직원 중에 최고연봉과 최저연봉을 출력해주세요.
  SELECT	MAX(연봉) AS 최고연봉, MIN(연봉) AS 최저 연봉 
  FROM	직원;

--3. 수강생정보 테이블에서 각 소속된 반별로 몇 명이 있는지 출력해주세요
  SELECT	소속반, COUNT(*) AS 반별인원수
  FROM  	수강생정보
  GROUP BY 소속반 ;

--4. 성적표 테이블에서 학생별로 국어와 영어 성적의 평균을 출력해주세요.
--(힌트 : 과목이 수학인 데이터는 제외하기)
  SELECT	학생ID, AVG(성적) AS 수학을제외한평균
  FROM	성적표
  WHERE 과목 != '수학'
  GROUP BY 학생ID ;

--5. 직원 테이블에서 부서별로 연봉의 합계를 출력해주세요
  SELECT  부서ID, SUM(연봉) AS 부서별연봉합계
  FROM    직원
  WHERE 부서ID IS NOT NULL
  GROUP BY 부서ID
  ORDER BY 부서ID;

--6. 직원 테이블과 직원 연락처 테이블을 이용해서 직원별로 연락처정보가 몇개 있는지 출력해주세요.
--직원 테이블을 기준으로 A0001 ~ A0011 의 모든 직원을 보여주되 , 연락처가 없는 대상도 0건으로
--출력되도록 해주세요. (단 , 조인시 오라클방식의 조인을 이용해보세요 )
--예) 직원 A0001 은 집전화, 휴대폰 둘다 가지고 있으므로 2개의 연락처 정보가 있습니다.
--직원 A0006 은 휴대폰 만 있으므로 1개의 연락처 정보가 있습니다.
--직원 A0009 은 연락처 정보가 없어서 0건을 표시하고 싶습니다. 
  SELECT	A.직원ID, COUNT(B.연락처) AS 연락처개수 
  FROM	직원 A , 직원연락처 B
  WHERE	A.직원ID = B.직원ID(+)
  GROUP BY A.직원ID;

2. HAVING

그룹화 상태의 데이터를 필터링(조건)



2.1. HAVING 주의사항

  1. SQL실행순서는 WHERE -> GROUP BY -> HAVING 순서이므로 HAVING 은 GROUP BY 의 영향을 받음!
    따라서 GROUP BY 에 입력된 컬럼에 의해서 입력 가능한 컬럼의 제약 발생

  2. 집계함수를 쓰면 HAVING에도 들어가야하고 일반 컬럼의 조건이면 WHERE에 들어가면 조건이 알맞을때가 잦음.

  3. WHERE 절에서는 집계함수 사용 X

--HAVING 잘 사용한 (예시)
SELECT 부서ID, SUM(연봉)
FROM 직원
GROUP BY 부서ID
HAVING 부서ID IN ( ‘D001’, ‘D002’ ) ;

SELECT 부서ID, SUM(연봉)
FROM 직원
GROUP BY 부서ID
HAVING SUM(연봉) >= 13000 ;

--SUM(연봉), AVG(연봉) 다수의 집계함수 사용
SELECT 부서ID, SUM(연봉), AVG(연봉)
FROM 직원
GROUP BY 부서ID
--SUM(연봉), AVG(연봉) 다수의 집계함수 사용함으로 조건으로
--SUM(연봉)와 AVG(연봉)을 HAVING 조건을 걸음
--(조건은 필요에 의해 사용)
HAVING SUM(연봉) >= 6000 
AND AVG(연봉) >= 5000;

--------------------------------------------

--HAVING 잘못된 사용 예시
SELECT 부서ID, SUM(연봉)
FROM 직원
GROUP BY 부서ID
HAVING 연봉 >= 6000 ;
-- 컬럼에 적용되는 일반조건이므로 HAVING -> WHERE
-- 또는 연봉 → SUM(연봉) 변경되야함

SELECT 부서ID, SUM(연봉) AS 연봉합계
FROM 직원
GROUP BY 부서ID
HAVING 연봉합계 >= 6000 ;
-- 연봉합계 → SUM(연봉) 변경되야함

2.2. HAVING 실습

--1. 수강생정보 테이블에서 소속반 별 인원수가 3명이상인 튜플(행)만 출력해주세요.
SELECT  소속반, COUNT(소속반) AS 인원수
FROM    수강생정보
GROUP BY 소속반
HAVING COUNT(소속반) >= 3;

--2.직원테이블 에서 부서별 최소연봉이 7500인 튜플(행)만 출력해주세요.

SELECT  부서ID, MAX(연봉) AS 최고연봉
FROM     직원   
GROUP BY 부서ID
HAVING MAX(연봉) = 7500;

--3.성적표 테이블 에서 학생별 평균 성적을 구하되, 평균 값이 NULL이 아닌 값만 출력하세요.
--(힌트 : HAVING 은 WHERE 절과 똑같이 NULL조건 사용가능)
SELECT  학생ID, ROUND(AVG(성적),1) AS 평균성적
FROM     성적표
GROUP BY 학생ID
HAVING AVG(성적) IS NOT NULL
ORDER BY 학생ID;
profile
제가 한 번 해보겠습니다.

0개의 댓글