일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- BM분석
- fundbox
- CAC
- allra
- 비즈니스모델
- pmf
- 선정산서비스
- 코호트
- 올라
- 머신러닝
- 전환율
- activation
- 활성화
- model_selection
- 데이터분석
- 팔방이익구조
- 퍼널분석
- 그로스해킹
- 셀프스토리지
- 역설구조
- retention
- 핀테크
- 한장으로끝내는비즈니스모델100
- 인게이지먼트
- aarrr
- mysql설치 #mysql #mysqluser #mysqlworkbench
- 서말리포켓
- 바로팜
- 리텐션
- sklearn
- Today
- Total
데이터로그😎
[SQL기본] 윈도우 함수 본문
1. 윈도우 함수 구성
MySQL의 윈도우 함수는 레코드 집합 전체 또는 특정 파티션에 대해 계산을 수행함녀서도 각 행을 그대로 유지하는 기능입니다. 주로 누적 합계, 순위, 이동 평균, 비율 등을 구할 때 사용됩니다.
함수명() OVER( PARTITION BY ..... ORDER BY.... ROWS BETWEEN ...AND..)
윈도우 함수는 <함수명> 뒤에 OVER 절이 옵니다. OVER 절 안에는 PARTITION BY/ ORDER BY/ ROWS BETWEN...AND 절에 올 수 있는데요, 각각의 기능은 다음과 같습니다.
구성 요소 | 기능 | 사용 목적 |
PARTITION BY | 데이터를 그룹별로 나눔 | 부서별, 지역별, 고객별 등 그룹 단위 계산 |
ORDER BY | 그룹 내에서 정렬 기준 지정 | 순위, 누적합, 이동 평균 등 순서 기반 함수 계산에 필수 |
ROWS BETWEEN | 정렬된 데이터에서 계산할 범위 지정 (프레임 절) | 슬라이딩 평균, 누적값 등에서 어디부터 어디까지 계산할지 명시 |
2. 윈도우 함수 종류
분석 목적 | 함수 | 설명 | 예시 |
누적 합계 | SUM(column) | 지정된 윈도우 내의 합계를 계산 | SUM(sales) OVER (ORDER BY date) |
평균 | AVG(column) | 윈도우 범위 내 평균값을 계산 | AVG(sales) OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) |
누적 개수 | COUNT(column) | 윈도우 내의 행 수를 카운트 | COUNT(*) OVER (PARTITION BY dept) |
최소 / 최대값 | MIN(column) / MAX(column) | 윈도우 내 최소/최대값 반환 | MAX(salary) OVER (PARTITION BY dept) |
순위 | RANK() | 동순위 인정, 순위 건너뜀 (1,1,3...) | RANK() OVER (ORDER BY score DESC) |
DENSE_RANK() | 동순위 인정, 순위 연속 (1,1,2...) | DENSE_RANK() OVER (ORDER BY score DESC) | |
고유 순번 | ROW_NUMBER() | 모든 행에 고유 순번 부여 (중복 없음) | ROW_NUMBER() OVER (ORDER BY score DESC) |
그룹 나누기 | NTILE(n) | 전체를 n개의 그룹으로 나눔 (동일한 행 수로 분할) | NTILE(4) OVER (ORDER BY score) |
이전 값 참조 | LAG(column, offset, default) | 지정한 이전 행의 값을 반환 | LAG(score, 1) OVER (ORDER BY id) |
다음 값 참조 | LEAD(column, offset, default) | 지정한 다음 행의 값을 반환 | LEAD(score, 1) OVER (ORDER BY id) |
첫 번째 값 | FIRST_VALUE(column) | 파티션 또는 정렬 범위 내 첫 번째 값 반환 | FIRST_VALUE(salary) OVER (PARTITION BY dept ORDER BY salary DESC) |
마지막 값 | LAST_VALUE(column) | 파티션 또는 정렬 범위 내 마지막 값 반환 | LAST_VALUE(salary) OVER (...) ※ 프레임 지정 필요 |
N번째 값 | NTH_VALUE(column, n) | 파티션 내 n번째 값 반환 | NTH_VALUE(salary, 2) OVER (...) |
누적 분포 | CUME_DIST() | 해당 값 이하의 비율 반환 (0~1), 하위 몇 %에 속하는가? | CUME_DIST() OVER (ORDER BY salary) "상위 10% 고객 찾기" 에서 사용할 수 있음 |
백분위 순위 | PERCENT_RANK() | 백분위 순위 (0부터 시작, 최댓값 1) | PERCENT_RANK() OVER (ORDER BY salary) |
전체 대비 비율 | SUM() + 나눗셈 | 전체 합 대비 현재 값의 비율 (수동 계산) | salary / SUM(salary) OVER () |
2023년 4월 기준 전국 주요 시/도의 연령대별 인구수 합계를 구하고, 연령대별 인구 비율 구하기
✅step1 :2023년 4월 기준 전국 주요 시/도의 연령대별 인구수 합계를 구하기
SELECT AGRDE_SE_CD, sum(POPLTN_CNT) pop_cnt
FROM tb_popltn
WHERE ADMINIST_ZONE_NO LIKE '__00000000'
AND POPLTN_SE_CD = 'T'
AND STD_MT = '202304'
GROUP BY AGRDE_SE_CD
ORDER BY AGRDE_SE_CD;
✅step2: step1의 테이블을 from 절에 subquery로 놓고 sum() over()를 사용해 집계.
** sum(pop_cnt) over() : pop_cnt 컬럼의 전체 합을 구할 수 있다.
SELECT *, pop_cnt/pop_total as pop_ratio
FROM
(SELECT *, SUM(pop_cnt) OVER() as pop_total
FROM (SELECT AGRDE_SE_CD, sum(POPLTN_CNT) as pop_cnt
FROM tb_popltn
WHERE STD_MT = '202304'
AND ADMINIST_ZONE_NO LIKE '__00000000'
AND POPLTN_SE_CD = 'T'
GROUP BY AGRDE_SE_CD
ORDER BY AGRDE_SE_CD) A) B;
SUM() OVER()가 뭔데?
SUM()은 주어진 열의 값을 합하는 데 사용되며 OVER()가 함께 사용될 때 윈도우 함수로 동작한다.
SUM() 함수를 OVER() 절과 함께 사용하면 특정 윈도우(ex. 파티션 or 순서) 내에서 합계를 계산할 수 있다.
여기서는 OVER() 안에 PARTITION BY나 ORDER BY 등을 사용하지 않았기에 pop_cnt 컬럼 전체의 합이 산출된 것.
자, 여기서 다시 한 번 예시를 들어볼까?
아래는 도시별 인구에 대한 표이다.
이 표로부터 국가별 인구 수 합계를 알고싶다면?? SUM() OVER()를 사용하면 된다.
SELECT * ,SUM(Population) OVER(PARTITION BY CountryCode) as country_pop
FROM city;
위의 표를 확인해보면 국가코드 별로, 즉 국가 별로 인구 수(population)의 합계인 country_pop 열이 생긴 것을 볼 수 있다.
만약.. 각 도시의 인구가 국가 전체에서 몇 %를 차지하는지 알고싶다면?
위의 쿼리를 subquery로 사용하면 되겠지?
SELECT *, Population/country_pop as pop_ratio
FROM (
SELECT * ,SUM(Population) OVER(PARTITION BY CountryCode) as country_pop
FROM city) A;
이전에 산출했던 쿼리를 from 절에 넣고, Population/country_pop 식을 SELECT 절에 추가하면, tada~~
전체 국가에서 각 도시의 인구가 차지하는 비율을 알 수가 있다!
'# 1. 언어 > # 1.1. SQL' 카테고리의 다른 글
[SQL기본] 문자열 처리: REPLACE, SUBSTR, LPAD, TRIM (0) | 2023.09.08 |
---|---|
[SQL기본] NULL vs 공백 / NULL 대체 (0) | 2023.09.08 |
서브 쿼리 (0) | 2023.09.06 |
ERD 표기법 (0) | 2023.09.06 |
python - mysql 연결 (0) | 2023.09.06 |