데이터 그룹화하기(GROUP BY)
GROUP BY
- 컬럼에서 동일한 값을 가지는 로우를 그룹화하는 키워드
- GROUP BY[컬럼 이름]형식으로 사용한다.
- 주로 그룹 별 데이터를 집계할 때 사용하며, 엑셀의 피벗 기능과 유사
- GROUP BY가 쓰인 쿼리의 SELECT절에는 GROUP BY 대상 컬럼과 그룹 함수만 사용 가능합니다.
- 만약 GROUP BY 대상 컬럼이 아닌 컬럼을 SELECT하면, 에러가 발생
- 여러 컬름으로 그룹화도 가능하며, 키워드 뒤에 [컬럼 이름]을 복수 개 입력하면 된다
- 컬럼 번호로도 그룹화가 가능
- 컬럼 번호는 SELECT절의 컬럼 이름의 순서를 의미
SELECT [GROUP BY 대상 컬럼 이름], ...,[그룹 함수]
FROM [테이블 이름]
WHERE조건식
GROUP BY [컬럼이름];
그룹에 조건 주기(HAVING)
HAVING
- 가져올 데이터 그룹에 조건을 지정하는 키워드
- HAVING 조건식 형식으로 사용
- 조건식이 True(참)이 되는 그룹만 선택
- HAVING 절의 조건식에서는 그룹 함수를 활용
SELECT[컬럼 이름], ..., [그룹 함수]
FROM [테이블 이름]
WHERE 조건식
GROUP BY[컬럼 이름]
HAVING 조건식;
다양한 글부 함수 알아보기(COUNT, SUM, AVG, MINMAX)
COUNT
- 그룹의 값 수를 세는 함수
- COUNT([컬럼 이름]) 형식으로 SELECT, HAVING 절에서 사용
- 집계할 컬럼 이름은 그룹의 기준이 되는 컬럼 이름과 같아도 되고, 같지 않아도 된다
- COUNT(1)은 하나의 값을 1로 세어주는 표현으로 COUNT 함수에 자주 사용
- GROUP BY 가 없는 쿼리에서도 사용 가능, 이때는 전체 로우에 함수가 적요
SELECT[컬럼 이름], ..., COUNT([컬럼 이름])
FROM [테이블 이름]
GROUP BY [컬럼 이름]
HAVING 조건문;
SUM
- 그룹의 합을 계산하는 함수
- SUM([컬럼 이름]) 형식으로 SELECT, HAVING 절에서 사용합니다
- 집계할 컬럼 이름은 그룹의 기준이 되는 컬럼 이름과 같아도 되고, 같지 않아도 된다
- GROUP BY가 없는 쿼리에서도 사용 가능하며, 이때는 전체 로우에 함수가 적용 된다
SELECT[컬럼 이름], ..., SUM([컬럼 이름])
FROM[테이블 이름]
GROUP BY[컬럼 이름]
HAVING 조건문;
AVG
- 그룹의 평균을 계산하는 함수
- AVG([컬럼 이름]) 형식으로 SELECT, HAVING 절에서 사용
- 집계할 컬럼 이름은 그룹의 기준이 되는 컬럼 이름과 같아도 되고, 같지 않아도 된다
- GROUP BY가 없는 쿼리에서도 사용 가능하며, 이때는 전체 로우에 함수가 적용
SELECT[컬럼 이름], ..., AVG([컬럼 이름])
FROM[테이블 이름]
GROUP BY[컬럼 이름]
HAVING 조건문;
MINMAX
- 그룹의 최솟값을 계산하는 함수
- MIN([컬럼 이름]) 형식으로 SELECT, HAVING 절에서 사용
- 집계할 컬럼 이름은 그룹의 기준이 되는 컬럼 이름과 같아도 되고, 같지 않아도 된다
- GROUP BY가 없는 쿼리에서도 사용 가능하며, 이때는 전체 로우에 함수가 적용
SELECT[컬럼 이름], ..., MIN([컬럼 이름])
FROM[테이블 이름]
GROUP BY[컬럼 이름]
HAVING 조건문;
쿼리 실행 순서 알아보기
- SELECT
- FROM
- WHERE
- GROUP BY
- HAVING
- ORDER BY
실습1
DROP DATABASE IF EXISTS pokemon;
CREATE DATABASE pokemon;
USE pokemon;
CREATE TABLE mypokemon(
number int,
name varchar(20),
type varchar(20),
height float,
weight float,
attack float,
defense float,
speed float
);
INSERT INTO mypokemon(number, name, type, height, weight, attack, defense, speed)
VALUES (10,'caterpie', 'bug',0.3,2.9,.30,35,45),
(25,'picachu','electric',0.4,6,55,40,90),
(27,'raichu','electric',0.8,30,90,55,110),
(133,'eevee','normal',0.3,6.5,55,50,55),
(152,'chikoirita','grass',0.9,6.4,49,65,45);
- 포켓몬 테이블에서 이름(name)의 길이가 5보다 큰 포켓몬들을 타입(type)을 기준으로 그룹화하고, 몸무게(weight)의 평균이 20 이상인 그룹의 타입과, 몸무게의 평균을 가져와 주세요. 이 때, 결과는 몸무게의 평균을 내림차순으로 정렬해 주세요
SELECT type, AVG(weight)
FROM mypokemon
WHERE LENGTH(name) > 5
GROUP BY type
HAVING AVG(weight) >= 20
ORDER BY 2 DESC;
- 포켓몬테이블에서 번호(number)가 200보다 작은 포켓몬들을 타입(type)을 기준으로 그룹화한 후에, 몸무게(weight)의 최댓값이 10보다 크거나 같고 최솟값은 2보다 크거나 같은 그룹의 타입, 키(height)의 최솟값, 최댓값을 가져와 주세요. 이 때, 결과는 키의 최솟값의 내림차순으로 정렬해 주고, 만약 키의 최솟값이 같다면 키의 최댓값의 내림차순으로 정렬해주세요
SELECT type, MIN(height), MAX(height)
FROM mypokemon
WHERE number < 200
GROUP BY type
HAVING MAX(weight) >= 10 AND MIN(weight) >= 2
ORDER BY 2 DESC, 3 DESC;
실습2
DROP DATABASE IF EXISTS pokemon;
CREATE DATABASE pokemon;
USE pokemon;
CREATE TABLE mypokemon(
number int,
name varchar(20),
type varchar(20),
height float,
weight float,
attack float,
defense float,
speed float
);
INSERT INTO mypokemon(number, name, type, height, weight, attack, defense, speed)
VALUES (10,'caterpie', 'bug',0.3,2.9,.30,35,45),
(25,'picachu','electric',0.4,6,55,40,90),
(27,'raichu','electric',0.8,30,90,55,110),
(133,'eevee','normal',0.3,6.5,55,50,55),
(152,'chikoirita','grass',0.9,6.4,49,65,45);
- 포켓몬의 타입 별 키의 평균을 가져와 주세요
SELECT type,AVG(height)
FROM mypokemon
GROUP BY type;
- 포켓몬의 타입 별 몸무게의 평균을 가져와 주세요
SELECT type,AVG(weight)
FROM mypokemon
GROUP BY type;
- 포켓몬의 타입 별 키의 평균과 몸무게의 평균을 함께 가져와 주세요
SELECT type,AVG(weight), AVG(height)
FROM mypokemon
GROUP BY type;
- 키의 평균이 0.5 이상인 포켓몬의 타입을 가져와 주세요
SELECT type
FROM mypokemon
GROUP BY type
HAVING AVG(height) >= 0.5;
- 몸무게의 평균이 20 이상인 포켓몬의 타입을 가져와 주세요
SELECT type
FROM mypokemon
GROUP BY type
HAVING AVG(weight) >= 20;
- 포켓몬의 타입 별 번호(number)의 합을 가져와 주세요
SELECT type, SUM(number)
FROM mypokemon
GROUP BY type;
- 키가 0.5 이상인 포켓몬이 포켓몬의 type 별로 몇 개씩 있는지 가져와 주세요
SELECT type,COUNT(*)
FROM mypokemon
WHERE height >= 0.5
GROUP BY type
- 포켓몬 타입 별 키의 최솟값을 가져와 주세요
SELECT type,MIN(height)
FROM mypokemon
GROUP BY type;
- 포켓몬 타입별 몸무게의 최댓값을 가져와 주세요
SELECT type, MAX(weight)
FROM mypokemon
GROUP BY type;
- 키의 최솟값이 0.5보다 크고 몸무게의 최댓값이 30보다 작은 포켓몬 타입을 가져와 주세요
SELECT type
FROM mypokemon
GROUP BY type
HAVING MIN(height) > 0.5 AND MAX(weight) < 30;