SQL | MySQL | Window Functions (2) - 집계 함수

2023. 3. 10. 00:06·SQL

 

 

 

 

 01. Window Functions - 윈도우 함수

 

 

  • MySQL 8.0부터 Window Functions이 도입됨 
  • OVER( ) 절을 사용해 지정된 윈도우 프레임에서 연산을 수행하는 함수
<window function> OVER (
    [PARTITION BY <partition expression>]
    [ORDER BY <order expression> [ASC|DESC], ... ]
    [<window frame clause>]
)

 

  • <window function>은 윈도우 함수를 넣으면 됨.
  • PARTITION BY은 GROUP BY와 같은 기능을 함

 

 👉 대표적인  윈도우 함수들

  •  ROW_NUMBER( )  :  각 행에 일련번호 부여 
  •  RANK( ) : 각 행의 순위를 할당(중복이 있을 경우 중복 값은 같은 순위 부여, 1,1,3등으로 넘어감)
  •  DENSE_RANK(  ) : 각 행의 순위를 할당(중복가능, 1, 1, 2,3... 순차적으로 순위부여)
  •  SUM( ), AVG( ), MIN( ), MAX( ), COUNT( ) : 윈도우 내에서 지정된 열의 합계, 평균, 최솟값, 최댓값, 개수 계산
  •  LEAD( ), LAG( ) : 현재 행 이전 또는 이후의 행의 값을 가져옴

 

 


 

 

02. 윈도우 함수 - 집계 함수

 

 

✅ 예제 테이블은 이전 포스팅 참고

https://boring9.tistory.com/49

 

SQL | MySQL | Window Functions (1) - 데이터 순위

01. Window Functions - 윈도우 함수 MySQL 8.0부터 Window Functions이 도입됨 OVER( ) 절을 사용해 지정된 윈도우 프레임에서 연산을 수행하는 함수 OVER ( [PARTITION BY ] [ORDER BY [ASC|DESC], ... ] [] ) 은 윈도우 함수를

boring9.tistory.com

 

 

✅ SUM 함수를 이용해 파티션별 윈도우의 합을 구할 수 있음.

 

✔️ 같은 지역에 있는 sale_amount의 합

SELECT 
    sale_region, sale_date, sale_amount,
    SUM(sale_amount) OVER(PARTITION BY sale_region) AS sum_sales
FROM  sales;

 

 

 

✔️ 같은 지역에 있는 sale_amount의 누적합

SELECT 
    sale_region, sale_date, sale_amount,
    SUM(sale_amount) OVER(PARTITION BY sale_region ORDER BY sale_amount) AS sum_sales
FROM  sales;

 

 

 

 

 

 

✅ MAX 함수를 이용해 파티션별 윈도우의 최댓값을 구할 수 있음.

 

✔️ 같은 지역에서 sale_amount의 최댓값

SELECT 
    sale_region, sale_date, sale_amount,
    MAX(sale_amount) OVER(PARTITION BY sale_region ) AS max_sales
FROM  sales;

 

 

 

✔️ 같은 지역에서 sale_amount의 최댓값을 가진 행만 추출

SELECT sale_region, sale_date, sale_amount
FROM (SELECT 
           sale_region, sale_date, sale_amount,
           MAX(sale_amount) OVER(PARTITION BY sale_region ) AS max_sales
           FROM  sales) AS aa
WHERE sale_amount = max_sales  ;

서브쿼리를 사용해서 지역별로 최댓값을 계산한 후 where문을 사용해 지역별 sale_amount가 최댓값인 행만 추출

 

 

하지만 위의 예제는 쿼리 성능이 저하될 수 있다.

파티션별 최댓값을 가진 행만 추출할 때는 RANK() 순위 함수를 사용하는게 적절

SELECT sale_region, sale_date, sale_amount
FROM (SELECT 
           sale_region, sale_date, sale_amount,
           RANK() OVER(PARTITION BY sale_region ORDER BY sale_amount DESC ) AS sale_rank
           FROM  sales) AS aa
WHERE sale_rank = 1  ;

 

 

 

 

 

 

✅ MIN 함수를 이용해 파티션별 윈도우의 최솟값을 구할 수 있음.

 

✔️ 같은 지역에서 sale_amount의 최솟값

SELECT 
    sale_region, sale_date, sale_amount,
    MIN(sale_amount) OVER(PARTITION BY sale_region) AS max_sales
FROM  sales;

 

 

 

 

✅ AVG 함수를 이용해 파티션별 윈도우의 평균을 구할 수 있음.

 

✔️ 같은 지역에서 sale_amount의 평균

SELECT 
    sale_region, sale_date, sale_amount,
    AVG(sale_amount) OVER(PARTITION BY sale_region) AS avg_sales
FROM  sales;

 

 

 

 

✅ COUNT 함수를 이용해 파티션별 윈도우의 평균을 구할 수 있음.

 

 

✔️ 밑의 'orders' 테이블은 각 고객의 주문수와 주문 액수 데이터이다.

✔️ COUNT() 함수와 윈도우 함수를 사용해 각 고객의 주문수를 계산

CREATE TABLE orders (
  order_id INT,
  customer_id INT,
  order_date DATE,
  order_amount DECIMAL(10,2)
);

INSERT INTO orders (order_id, customer_id, order_date, order_amount) VALUES
(1, 1, '2022-01-01', 100.00),
(2, 1, '2022-01-02', 50.00),
(3, 2, '2022-01-01', 75.00),
(4, 2, '2022-01-03', 200.00),
(5, 2, '2022-01-05', 150.00);

 

orders 테이블

 

SELECT
  customer_id,
  COUNT(*) OVER(PARTITION BY customer_id) AS order_count, /* 고객별 주문건수 */
  SUM(order_amount) OVER(PARTITION BY customer_id) AS total_amount /*고객별 총주문량*/
FROM orders;

 

 

 

✔️ DISTINCT 문을 사용해서 고객 id의 중복을 없앨 수 있음.

SELECT
  DISTINCT customer_id,
  COUNT(*) OVER(PARTITION BY customer_id) AS order_count,
  SUM(order_amount) OVER(PARTITION BY customer_id) AS total_amount
FROM orders;

 

 

 

 

 

 

 

 

 


출처 및 참고 문헌(reference)

더보기

https://dev.mysql.com/doc/refman/8.0/en/window-functions.html

 

MySQL :: MySQL 8.0 Reference Manual :: 12.21 Window Functions

 

dev.mysql.com

 

 

 

'SQL' 카테고리의 다른 글

SQL | MySQL | 테이블 집합 연산 - UNION, UNION ALL 등  (0) 2023.03.15
SQL | MySQL | JOIN - inner, left, right  (0) 2023.03.15
SQL | MySQL | Window Functions (1) - 데이터 순위  (0) 2023.03.09
SQL | MySQL | 그룹에 따른 집계 - GROUP BY, HAVING  (0) 2023.03.09
SQL | MySQL | 내장 함수(2) - 날짜, 시간 함수  (0) 2023.03.09
'SQL' 카테고리의 다른 글
  • SQL | MySQL | 테이블 집합 연산 - UNION, UNION ALL 등
  • SQL | MySQL | JOIN - inner, left, right
  • SQL | MySQL | Window Functions (1) - 데이터 순위
  • SQL | MySQL | 그룹에 따른 집계 - GROUP BY, HAVING
갬보리
갬보리
제발 코드정리좀 하자 (R, SQL, SAS, Python , etc...)
  • 갬보리
    보딩코
    갬보리
  • 전체
    오늘
    어제
    • 분류 전체보기 (50) N
      • R (32)
        • dplyr (7)
        • preprocessing (2)
        • EDA (0)
        • ggplot2 (10)
        • plotly (11)
        • leaflet (2)
      • SQL (15)
      • SAS (0)
      • Python (1)
        • preprocessing (0)
        • Library (0)
      • ETC (2) N
        • ML (1) N
  • hELLO· Designed By정상우.v4.10.3
갬보리
SQL | MySQL | Window Functions (2) - 집계 함수
상단으로

티스토리툴바