MySQL Window 함수 / RANK / SUM OVER / 날짜 데이터 이해하기 | 내일배움캠프 25.05.15 (목) TIL

soomin Yun (윤수민)·2025년 5월 15일
0

📌오늘의 학습 키워드
WINDOW 함수
RANK
SUM () OVER ()
DATE
DATE_FORMAT

📖오늘 학습한 내용을 나만의 언어로 정리하기

Window 함수란?

행을 단위로 묶어주어 단위 안에서의 연산을 쉽게 할 수 있도록 해준다.
(예시) 한식/중식/일식 별로 주문수 랭킹을 구하기

Window 함수 : (1) RANK 함수

RANK 함수란?

특정 기준으로 순위를 매겨주는 기능이다.

RANK() OVER(partition by 칼럼명 order by 칼럼명 desc)로 적어준다.

-- 음식 타입별로 주문 건수가 가장 많은 상점 3개씩 조회하기 == 순위를 매긴 다음에 3위까지만 조회한다. 
-- 1) base 데이터 만들기 : 음식 타입별, 음식점별 주문 건수 만들기
-- 2) rank 함수 적용하기
-- 3) 3위까지 조회하고, 음식 타입별, 순위별로 정렬하기 


select cuisine_type,
       restaurant_name,
       cnt_order,
       ranking
from
(
select cuisine_type,
       restaurant_name,
       cnt_order,
       rank() over (partition by cuisine_type order by cnt_order desc) ranking
       # window 함수에서 over()은 짝꿍처럼 붙어서 써준다. 
       # rank 뒤의 괄호에는 아무런 값을 작성하지 않아도 된다. 
       # partition by 뒤에는 구분해줄 칼럼명을 작성 == cuisine_type을 기준으로 구분
       # order by 뒤에는 랭킹의 순서를 정해줄 칼럼명을 작성 == cnt_order를 기준으로 내림차순
from 
(
select cuisine_type,
       restaurant_name, 
       count(*) cnt_order
from food_orders
group by 1,2
) a
) b
where ranking <=3

Window 함수 : (2)누적합 구하기

sum(칼럼명 1) over(partition by 칼럼명2)로 적어준다.

-- 각 음식점의 주문건이 해당 음식 타입에서 차지하는 비율을 구하고, 
-- 주문건이 낮은 순으로 정렬했을 때 누적 합 구하기 

-- 1) 음식 타입별 주문건의 합계 구하기 : base 데이터 // 음식점별로 주문건수 구하기
-- 2) 주문건이 낮은 순으로 정렬했을 때 누적합 구하기 


select cuisine_type,
       restaurant_name,
       cnt_order,
       sum(cnt_order) over (partition by cuisine_type) sum_cuisine, #음식 타입별 주문건수의 합
       sum(cnt_order) over (partition by cuisine_type order by cnt_order) cum_cuisine #음식 타입별 주문건수의 누적합
from 
(
select cuisine_type,
       restaurant_name,
       count(*) cnt_order
from food_orders
group by 1,2
) a
order by cuisine_type, cnt_order


이런 값을 도출할 수 있다.

주문건수(cnt_order)가 동일한 값은 우열을 가릴 수 없다고 판단하여, 누적합(cum_cuisine)이 모두 동일하게 나타나는 것이다.


날짜 데이터 다루기

SQL에는 문자형/숫자형/날짜형 데이터가 있다.

날짜형 데이터는 왜 필요한가?

문자형 데이터로 되어있는 날짜 데이터에서 (EX. 2025-01-01) 특정 날짜 형식(EX.년, 월, 일)만 추출하려면 SUBSTR 함수를 사용해서 복잡하게 구해야 한다. 하지만 날짜형 데이터를 사용하면 비교적 간단하게 추출이 가능하다. (=DATE 형식을 지정하기 편리하다)

1) 문자형 데이터를 날짜형 데이터로 바꾸기

DATE(칼럼명)

2) 문자형 데이터의 형식(FORMAT)을 바꾸기

DATE_FORMAT (DATE(칼럼명), '%Y') "년"

%m은 월, %d는 일, %w는 요일이다.
만약 연도 + 월 데이터 형식을 만들고 싶다면 '%Y%m'로 작성해주면 된다.

-- 년도별 3월의 주문건수 구하기


select date_format(date(date), '%Y') "년",
       date_format(date(date), '%m') "월",
       date_format(date(date), '%Y%m') "년월",
       count(*) "주문건수"
from food_orders f inner join payments p on f.order_id=p.order_id
where date_format(date(date), '%m') = '03'
group by 1,2,3
order by 1 


위와 같은 데이터를 구할 수 있다.

❌학습하며 겪었던 문제점 & 에러
테이블에 없는 값까지 생성하는(?) WITH RECURSIVE 함수를 써야하는지 혼란이 왔다.

🎯내일 학습할 내용
김문래 튜터님의 문제 해설을 보고, 나의 쿼리 논리구조가 맞는지 확인해 볼 것이다.

profile
안녕하세요 :)

0개의 댓글