GROUP BY를 이용할 때 집계 함수를 정말 많이 썼다!
그 때 사용한 집계함수에 대해 알아보자.
count(*) : 정해진 집합 레벨에서 데이터 건수를 가져옴
count(distinct ‘column’) : 정해진 집합 레벨에서 중복을 제외하고 고유한 건수를 가져옴
sum() : 정해진 집합 레벨에서 지정된 컬럼의 총합을 가져옴
min() : 정해진 집합 레벨에서 지정된 컬럼의 최소값을 가져옴
max() : 정해진 집합 레벨에서 지정된 컬럼의 최대값을 가져옴
avg() : 정해진 집합 레벨에서 지정된 컬럼의 평균값을 가져옴
| order_id | user_id | product_id | order_number |
|---|---|---|---|
| 235622 | 1 | 1 | 1 |
| 235622 | 1 | 1 | 1 |
| 235622 | 1 | 1 | 2 |
| 235622 | 1 | 1 | 2 |
| 934711 | 1 | 2 | 2 |
| 235622 | 1 | 2 | 2 |
| 235622 | 1 | 2 | 3 |
| 934711 | 1 | 2 | 3 |
| 638298 | 1 | 2 | 4 |
예를 들어 위와 같은 데이터가 있을 때 아래 코드들을 실행하면 어떤 결과가 나오는지 보자
select user_id, count(*) as cnt
from orders
group by user_id
결과
| user_id | cnt |
|---|---|
| 1 | 9 |
user_id로 group by를 실행하고 그 건수를 가져오는 count(*)함수를 썼으니 결과는 위와 같이 나온다.
select user_id, count(distinct product_id) as cnt
from orders
group by user_id
결과
| user_id | cnt |
|---|---|
| 1 | 2 |
user_id 별로 주문한 product_id의 고유한 데이터 건수(1과 2)를 가져오게 된다.
select user_id, count(distinct order_id) as cnt
from orders
group by user_id
결과
| user_id | cnt |
|---|---|
| 1 | 3 |
user_id 별로 주문한 order_id의 고유한 데이터 건수(235622, 934711, 638298)를 가져오게 된다.
집계 함수를 사용할 때 주의할 점이 있는데 집계 함수는 ‘Null’값을 계산하지 않는다.
| empno | job | sal | comm | deptno |
|---|---|---|---|---|
| 1 | SALES | 3,456 | 300 | 10 |
| 2 | SALES | 3,456 | 600 | 10 |
| 3 | MANAGER | 5,632 | 600 | 20 |
| 4 | SALES | 4,232 | Null | 10 |
| 5 | MARKETING | 3,562 | 700 | 30 |
| 6 | SALES | 4,251 | Null | 30 |
| 7 | MANAGER | 6,342 | 400 | 20 |
| 8 | MARKETING | 5,452 | 1200 | 10 |
위와 같은 데이터가 있을 때 아래 코드를 실행해보자
select deptno, count(*) as cnt, sum(comm) as sum, avg(comm) as avg
from emp
group by deptno
결과
| deptno | cnt | sum | avg |
|---|---|---|---|
| 10 | 4 | 2100 | 700 |
| 20 | 2 | 1000 | 500 |
| 30 | 2 | 700 | 700 |
결과를 보면 Null값이 계산에 포함되지 않았기 때문에 avg 값이 sum/cnt 가 아닌 것을 볼 수 있다.
min(), max()는 숫자값 뿐만 아니라 문자, 날짜, 시간형도 가능하지만 sum(), avg()는 숫자형만 가능하다.
| empno | name | job | hiredate | deptno |
|---|---|---|---|---|
| 1 | CLARK | SALES | 2002-10-01 | 10 |
| 2 | ALLEN | SALES | 1998-02-17 | 10 |
| 3 | BLAKE | MARKETING | 2021-09-03 | 10 |
| 4 | TURNER | CLERK | 2015-03-21 | 10 |
위와 같은 데이터가 있을 때 아래 코드를 실행해보자
select max(name) as name, min(job) as job, max(hiredate) as max_hire, min(hiredate) as min_hire
from emp
group by deptno;
결과
| name | job | max_hire | min_hire |
|---|---|---|---|
| TURNER | CLERK | 2021-09-03 | 1998-02-17 |
max(날짜) 는 제일 최근 날짜를 가져오고, min(날짜)는 제일 오래된 날짜를 가져온다.
저기서 select sum(name), avg(job) 을 사용하면 문자열을 사용했다는 에러가 뜨게 된다.
max(문자열) 을 사용했을 때 영어의 경우 ASCII 코드를 기준으로 대문자<소문자 로 인식하게 되고, 한글의 경우에는 UNICODE를 기준으로 자음<모음<한글 이 된다.
숫자와 한글, 영어를 비교하면
특수 문자 < 숫자 < 영문 < 한글
위와 같은 순서가 된다.