오늘은 MySQL 데이터 그룹화하기에 대해서 알아보도록 하겠습니다.
데이터 그룹화하기 (GROUP BY)
데이터 그룹화란 엑셀에서 피벗을 활용하여 원하는 데이터를 그룹화하는 기능과 유사합니다. "고객 등급 별 매출 통계 뽑아주세요", "상품 카테고리 별 실적 통계 뽑아주세요" 등 데이터를 그룹화해서 통계 낼 때 사용됩니다. 컬럼에서 동일한 값을 가지는 로우를 그룹화하는 키워드는 GROUP BY입니다.
GROUP BY 특징
- GROUP BY [컬럼 이름] 형식으로 사용합니다.
- 주로 그룹 별 데이터를 집계할 때 사용하며, 엑셀의 피벗 기능과 유사합니다.
- GROUP BY가 쓰인 쿼리의 SELECT 절에는 GROUP BY 대상 컬럼과 그룹 함수만 사용 가능합니다.
- 만약, GROUP BY 대상 컬럼이 아닌 컬럼을 SELECT 하면, 에러가 발생합니다.
- 여러 컬럼으로 그룹화도 가능하며, 키워드 뒤에 [컬럼 이름]을 복수 개 입력하면 됩니다.
- 컬럼 번호로도 그룹화가 가능합니다.
- 이때, 컬럼 번호는 SELECT 절의 컬럼 이름의 순서를 의미합니다.
GROUP BY 쿼리 문법
SELECT [GROUP BY 대상 컬럼 이름], ..., [그룹 함수]
FROM [테이블 이름]
WHERE 조건식
GROUP BY [컬럼 이름];
-> GROUP BY는 WHERE 다음에 위치하게 되며 SELECT 뒤에는 GROUP BY 대상 컬럼 이름과 그룹 함수만 올 수 있습니다.
그룹에 조건 추가 (Having)
가져올 데이터 그룹에 조건을 지정해주는 키워드는 HAVING입니다.
HAVING의 특징
- HAVING 조건식 형식으로 사용합니다.
- 조건식이 True(참)이 되는 그룹만 선택합니다.
- HAVING 절의 조건식에는 그룹 함수를 활용합니다.
HAVING 쿼리 문법
SELECT [컬럼 이름],..., [그룹 함수]
FROM [테이블 이름]
WHERE 조건식
GROUP BY [컬럼 이름]
HAVING 조건식;
-> HAVING은 GROUP BY 다음에 위치하게 되며 그룹들 중에서 진짜로 가져오고 싶은 그룹들의 조건을 지정해 줍니다.
다양한 그룹 함수 알아보기 (COUNT, SUM, AVG, MINMAX)
COUNT의 특징
- 그룹의 값 수를 세는 함수
- COUNT([컬럼 이름]) 형식으로 SELECT, HAVING 절에서 사용합니다.
- 집계할 컬럼 이름은 그룹의 기준이 되는 컬럼 이름과 같아도 되고, 같지 않아도 됩니다.
- COUNT(1)은 하나의 값을 1로 세어주는 표현으로 COUNT 함수에 자주 사용합니다.
- GROUP BY가 없는 쿼리에서도 사용 가능하며, 이때는 전체 로우에 함수가 적용됩니다.
COUNT 쿼리 문법
SELECT [컬럼 이름], ..., COUNT([컬럼 이름])
FROM [테이블 이름]
GROUP BY [컬럼 이름]
HAVING 조건문;
SUM의 특징
- 그룹의 합을 계산하는 함수
- SUM([컬럼 이름]) 형식으로 SELECT, HAVING 절에서 사용합니다.
- 집계할 컬럼 이름은 그룹의 기준이 되는 컬럼 이름과 같아도 되고, 같지 않아도 됩니다.
- GROUP BY가 없는 쿼리에서도 사용 가능하며, 이때는 전체 로우에 함수가 적용됩니다.
SUM 쿼리 문법
SELECT [컬럼 이름], ..., SUM([컬럼 이름])
FROM [테이블 이름]
GROUP BY [컬럼 이름]
HAVING 조건문;
-> 한 가지 팁은 그룹의 기준이 되는 컬럼 이름을 함께 SELECT 해야 의미를 파악할 수 있습니다.
AVG의 특징
- 그룹의 평균을 계산하는 함수
- AVG([컬럼 이름]) 형식으로 SELECT, HAVING 절에서 사용합니다.
- 집계할 컬럼 이름은 그룹의 기준이 되는 컬럼 이름과 같아도 되고, 같지 않아도 됩니다.
- GROUP BY가 없는 쿼리에서도 사용 가능하며, 이때는 전체 로우에 함수가 적용됩니다.
AVG 쿼리 문법
SELECT [컬럼 이름], ..., AVG([컬럼 이름])
FROM [테이블 이름]
GROUP BY [컬럼 이름]
HAVING 조건문;
-> 한 가지 팁은 그룹의 기준이 되는 컬럼 이름을 함께 SELECT 해야 의미를 파악할 수 있습니다.
MIN의 특징
- 그룹의 최솟값을 계산하는 함수
- MIN([컬럼 이름]) 형식으로 SELECT, HAVING 절에서 사용합니다.
- 집계할 컬럼 이름은 그룹의 기준이 되는 컬럼 이름과 같아도 되고, 같지 않아도 됩니다.
- GROUP BY가 없는 쿼리에서도 사용 가능하며, 이때는 전체 로우에 함수가 적용됩니다.
MIN 쿼리 문법
SELECT [컬럼 이름], ..., MIN([컬럼 이름])
FROM [테이블 이름]
GROUP BY [컬럼 이름]
HAVING 조건문;
<예시 1>
SELECT type, COUNT(*), COUNT(1), AVG(height), MAX(weight)
FROM pokemon.mypokemon
GROUP BY type;
-> 실행하게 되면 첫 번째 열에는 그룹화한 type 값들이 오게 됩니다. 다음으로 COUNT(*)는 그룹별 전체 로우수를 세어서 결과로 나타냅니다. 다음으로 COUNT(1)은 그룹별 로우를 하나의 값을 1로 치환해서 합을 보여줍니다. 다음은 키의 평균값이 반환됩니다. 마지막으로 몸무게의 최댓값이 반환됩니다.
<예시 2>
SELECT type, COUNT(*), COUNT(1), AVG(height), MAX(weight)
FROM pokemon.mypokemon
GROUP BY type;
HAVING COUNT(1) = 2;
-> 실행하게 되면 예시 1의 결괏값에서 COUNT(1) = 2의 조건을 만족하는 그룹만 출력됩니다.
쿼리 실행 순서 알아보기
MySQL 쿼리문의 6가지 핵심 쿼리 키워드를 정리해보겠습니다.
키워드 | 문법 | 작성 순서 | 실행 순서 |
SELECT | SELECT [컬럼 이름] | 1 | 5 |
FROM | FROM [테이블 이름] | 2 | 1 |
WHERE | WHERE 조건식 | 3 | 2 |
GROUP BY | GROUP BY [컬럼 이름] | 4 | 3 |
HAVING | HAVING 조건식 | 5 | 4 |
ORDER BY | ORDER BY [컬럼 이름] | 6 | 6 |
mypokemon | ||||
number | name | type | height | weight |
10 | caterpie | bug | 0.3 | 2.9 |
25 | pikache | electric | 0.4 | 6 |
26 | raichu | electric | 0.8 | 30 |
125 | electabuzz | electric | 1.1 | 30 |
133 | eevee | normal | 0.3 | 6.5 |
137 | porygon | normal | 0.8 | 36.5 |
152 | chikorita | grass | 0.9 | 6.4 |
153 | bayleef | grass | 1.2 | 15.8 |
172 | pichu | electric | 0.3 | 2 |
470 | leafeon | grass | 1 | 25.5 |
위와 같은 데이터 베이스가 있을 때 아래와 같은 쿼리문을 작성하여 어떠한 순서로 실행이 진행되는지 단계별로 살펴보겠습니다.
SELECT type, COUNT(1), MAX(weight) -> 실행 순서 5
FROM pokemon.mypokemon -> 실행순서 1
WHERE name LIKE '%a%' -> 실행 순서 2
GROUP BY type -> 실행순서 3
HAVING MAX(height) > 1 -> 실행순서 4
ORDER BY3: -> 실행순서 6
SELECT type, COUNT(1), MAX(weight) -> 실행순서 5
FROM pokemon.mypokemon -> 실행순서 1
WHERE name LIKE '%a%' -> 실행순서 2
GROUP BY type -> 실행순서 3
HAVING MAX(height) > 1 -> 실행순서 4
ORDER BY3: -> 실행순서 6
-> 실행순서 1은 pokemon이라는 데이터 베이스에서 mypokemon이라는 테이블을 불러오는 쿼리문입니다.
SELECT type, COUNT(1), MAX(weight) -> 실행순서 5
FROM pokemon.mypokemon -> 실행순서 1
WHERE name LIKE '%a%' -> 실행순서 2
GROUP BY type -> 실행순서 3
HAVING MAX(height) > 1 -> 실행순서 4
ORDER BY3: -> 실행순서 6
-> 실행 순서 2는 WHERE절에서 name열에서 a를 포함하는 열을 가져오라는 쿼리문입니다. 실행하면 아래 테이블과 같이 name에 a를 포함하는 로우만 남게 됩니다.
mypokemon | ||||
number | name | type | height | weight |
10 | caterpie | bug | 0.3 | 2.9 |
25 | pikache | electric | 0.4 | 6 |
26 | raichu | electric | 0.8 | 30 |
125 | electabuzz | electric | 1.1 | 30 |
152 | chikorita | grass | 0.9 | 6.4 |
153 | bayleef | grass | 1.2 | 15.8 |
470 | leafeon | grass | 1 | 25.5 |
SELECT type, COUNT(1), MAX(weight) -> 실행순서 5
FROM pokemon.mypokemon -> 실행순서 1
WHERE name LIKE '%a%' -> 실행순서 2
GROUP BY type -> 실행순서 3
HAVING MAX(height) > 1 -> 실행순서 4
ORDER BY3: -> 실행순서 6
-> 실행순서 3은 type을 기준으로 그룹화를 합니다. 그룹화를 하면 아래 테이블과 같이 정리됩니다.
mypokemon | ||||
type | number | name | height | weight |
bug | 10 | caterpie | 0.3 | 2.9 |
electric | 25 | pikachu | 0.4 | 6 |
26 | raichu | 0.8 | 30 | |
125 | electabuzz | 1.1 | 30 | |
grass | 152 | chikorita | 0.9 | 6.4 |
153 | bayleef | 1.2 | 15.8 | |
470 | leafeon | 1 | 25.5 |
SELECT type, COUNT(1), MAX(weight) -> 실행순서 5
FROM pokemon.mypokemon -> 실행순서 1
WHERE name LIKE '%a%' -> 실행순서 2
GROUP BY type -> 실행순서 3
HAVING MAX(height) > 1 -> 실행순서 4
ORDER BY3: -> 실행순서 6
-> 실행 순서 4를 진행하면 각 그룹별 height의 max값이 1이 넘는 그룹만 남습니다. 해당하는 그룹은 electric과 grass 뿐입니다. 아래와 같은 데이터만 남게 됩니다.
mypokemon | ||||
type | number | name | height | weight |
electric | 25 | pikachu | 0.4 | 6 |
26 | raichu | 0.8 | 30 | |
125 | electabuzz | 1.1 | 30 | |
grass | 152 | chikorita | 0.9 | 6.4 |
153 | bayleef | 1.2 | 15.8 | |
470 | leafeon | 1 | 25.5 |
SELECT type, COUNT(1), MAX(weight) -> 실행 순서 5
FROM pokemon.mypokemon -> 실행순서 1
WHERE name LIKE '%a%' -> 실행 순서 2
GROUP BY type -> 실행순서 3
HAVING MAX(height) > 1 -> 실행순서 4
ORDER BY3: -> 실행순서 6
-> 실행 순서 5를 거치게 되면 각그룹별 로우값을 1로 하여 합을한 결과가 나오고 weight의 최대값이 결과로 반환됩니다.
type | COUNT(1) | MAX(weight) |
electric | 3 | 3 |
grass | 3 | 25.5 |
SELECT type, COUNT(1), MAX(weight) -> 실행순서 5
FROM pokemon.mypokemon -> 실행순서 1
WHERE name LIKE '%a%' -> 실행 순서 2
GROUP BY type -> 실행순서 3
HAVING MAX(height) > 1 -> 실행순서 4
ORDER BY 3: -> 실행순서 6
-> 실행순서 6을 거치게 되면 3번째 열인 MAX(weight)의 오름차순으로 정렬합니다. 결괏값은 아래 테이블과 같습니다.
type | COUNT(1) | MAX(weight) |
grass | 3 | 25.5 |
electric | 3 | 30 |
이상으로 MySQL에서 데이터 그룹화하는 방법에 대해서 알아보았습니다.
'데이터 분석 및 업무 자동화' 카테고리의 다른 글
평범한 직장인의 파이썬 독학 기록 - 리스트, 딕셔너리, 함수 (0) | 2022.02.05 |
---|---|
직장인 파이썬 독학 기록 - 왕기초편 (0) | 2022.02.04 |
빅데이터 전문가 되는 법 (0) | 2022.01.26 |
MySQL로 데이터분석 해보자 - ORDER BY, RANK (0) | 2022.01.24 |
파워비아이 DAX 함수, TABLE과 FILTER를 알아보자 (0) | 2022.01.19 |
댓글