개발/기타 개인 공부

SQL 기본 4. 그룹/집계 함수의 이해

잠수돌침대 2022. 12. 21. 17:02

데이터 분석을 함에 있어서 데이터를 묶는 Join과 더불어 양대산맥 위치쯤에 있는 Group by, Aggregation 함수라 카더라.

일단 group by가 뭐 하는 함수인지 대충 살펴보고 넘어가자.

 

Group by는 뭐하는 거야?

 

group by는 특정 컬럼의 똑같은 값을 기준으로 그룹핑을 해주는 키워드

group by 키워드 다음으로 적힌 컬럼 값으로 그룹화를 하면 다른 집계 함수(Aggregation function)와 함께 사용할 수 있음

 

이는 다시 말해?

Select 절에는 group by 절에 기술된 컬럼의 이름(또는 가공된 컬럼)과 집계 함수만 사용되어야 한다.
그 외의 것들이 있을 경우에는 오류를 발생

 

여기서 가지는 그룹핑의 또 한 가지 특징!

💡특정 컬럼을 이용하여 그룹핑을 진행할 경우, 그 컬럼의 값은 Unique 한 특성을 지닌다.(사실 그럴 수밖에 없지!)
= 이는 1:M 관계에서 1의 집합에 해당된다는 의미와 동치

 

아래는 group by를 하는 하나의 예시 집계 함수와 기술된 컬럼만 select 구문에 사용된 것을 확인할 수 있음 

select somnum, count(*) as som_count
, sum(grade) as sum_grade
, avg(sal) as avg_sal
, max(grade) as max_grade
from a_table
group by somnum; -- somnum을 기준으로 그룹핑

 

group by 내 세부적인 필터링을 주고 싶을 경우 having 키워드를 사용하여 필터링할 수 있다.

-- 사용될 수 있는 키워드의 구체적인 예시
select <columns>
from <table>
where <condition>
group by <columns>
having <group_condition>
order by <columns>

 

필터링 종류에 따른 차이점

where 구문 : 그룹핑을 진행하기 전 필터링

having 구문 : 그룹핑을 진행한 후 필터링

 

group by가 실제로 적용되는 내부 로직

 

1. group by 절을 기준으로 각 테이블이 분할됨

 

2. group by 컬럼값 레벨로 사용된 집계 함수를 적용함

 

3. 적용된 집계 함수 데이터를 테이블에 합침

 


집계 함수(Aggregation)

 

집계 함수에는 여러 종류가 있다. 그중 가장 많이 사용되는 것들을 테이블로 정리해서 표현하면 다음과 같다.

함수 유형 설명
count(*) 정해진 집합 레벨 내 데이터의 개수 반환
count(distinct 컬럼이름) 정해진 집합 레벨 내 중복 배제한 고유한 데이터 개수 반환
sum(컬럼 이름) 정해진 집합 레벨 내 컬럼값의 총 합 반환
min(컬럼 이름) 정해진 집합 레벨 내 컬럼값의 최소값 반환
max(컬럼 이름) 정해진 집합 레벨 내 컬럼값의 최대값 반환
avg(컬럼 이름) 정해진 집합 레벨 내 컬럼값의 평균값 반환

그 외에도 정말 많은 것이 있지만, 크게 count, sum, min, max, avg를 주로 사용한다.

 

아래는 집계 함수의 까먹을 수 있는 특징!

1. 집계 함수는 null을 계산하지 않는다.
2. min, max 함수의 경우 숫자 뿐만이 아닌 문자열, 날짜/시간도 반환할 수 있다.
3. 반면에 sum, avg숫자만 가능함에 유의한다.

distinct는 뭐임

 

일종의 추가 필터링이라 생각하는 게 편해 보임. 카운트를 하되, 해당 컬럼에서의 중복값은 count에서 배제한 후 시행

ex ) 아래의 '주문' 테이블을 주문일자 컬럼을 기준으로 그룹핑해야 하는 상황

학번 이름 주문일자 가격
101 김땡땡 12/31 1000
101 김땡땡 12/31 2500
102 한땡땡 11/20 800
select 주문일자, count(*) as 하루배송건 from 주문 group by 주문일자
-- count의 결과로 12/31 건의 값은 2가 나올 것

 

 

하지만 이를 학번으로 distinct(추가 필터링)을 걸게 되면, 같은 학번인 101은 한 번만 카운트함

select 주문일자, count(distinct 학번) as 하루배송건 from 주문 group by 주문일자
-- count의 결과로 12/31 건의 값은 중복을 뺀 1이 나올 것

 


avg을 사용하면서 특정 소수점에서 반올림을 하고 싶을 경우 round 함수를 사용하도록 한다.

select round(avg(sal), 2) as avg_sal; -- 각 평균 급여를 소수점 둘째자리까지 표기

 

condition으로 python의 in 기능을 그대로 사용할 수 있다. 이때, 함수의 인자를 넘기는 방식으로 '이것들 중 하나가 포함되어 있는지'에 대한 필터링이 가능

where a.name in('Sungmin', 'Lion') -- a 테이블 내 name이 Sungmin 또는 Lion인 경우에만 필터링