2023. 9. 4. 10:37ㆍDATA PROGRAMMING/SQL
윈도우함수는 행과 행간의 관계에서 다양한 연산 처리를 할 수 있는 함수이다. 분석함수로 알려져 있으며 일반적으로 윈도우함수는 일반함수와 달리 중첩하여 호출 될 수는 없다.
윈도우 함수
윈도우 함수의 종류
- 순위관련함수
- 집계관련함수
- 행순서관련함수
- 그룹내 비율관련함수
순위관련함수
RANK() : 그룹내 순위를 알려줌 (동일값 동일 순위) ex) 1위, 2위, 2위, 3위
DENSE_RANK() : 그룹내 순위를 알려줌 (동일값 동일 순위) ex) 1위, 2위, 2위, 3위
ROW_NUMBER : 동일값이라도 무조건 순위를 정함 말그대로 행번호를 지정해 줌
사용 예시
RANK() over (partition by 부서 ORDER BY 생년월일) : 부서별로 묶어서 생년월일 순위를 알 수 있음
예제 1
SELECT
country,
customerCount,
RANK() OVER (ORDER BY customerCount DESC) AS customerRank
FROM (
SELECT
country,
COUNT(*) AS customerCount
FROM
s_customers
GROUP BY
country
) AS counts
ORDER BY
customerRank ASC,
country ASC;
집계관련함수
집계관련함수는 SUM(), AVG() 등 이미 사용하고 있던 함수들이다. 하지만 윈도우 함수의 PARTITION BY 등의 기능을 통해 좀 더 세부적이고 자세하게 집계관련함수를 사용할 수 있다.
예제2
SELECT productLine, name, quantityInStock,
SUM(quantityInStock) OVER
(
PARTITION BY productLine
ORDER BY quantityInStock DESC
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS noOfQuantitys_sum
FROM s_products
ORDER BY productLine, quantityInStock desc
여기서 PARTITION BY productLine은 productLine 별로 총계를 보겠다는 것이다.
RANGE는 논리적인 값 기준으로 행을 구분한다 이에 값이 같다면 같은 값으로 처리한다. RANGE 외에 ROW를 사용하면 물리적으로 행을 구분할 수 있다.
BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING은 UNBOUNDED PRECEDING(가장 윗 경계)
와 UNBOUNDED FOLLOWING(가장 아랫 경계) 모두의 범위에서 값을 집계 한다는 것인데, 같은 productLine 전체의 집계를 하겠다는 뜻이다.
예제 3
SELECT productLine, name, quantityInStock,
SUM(quantityInStock) OVER
(
PARTITION BY productLine
ORDER BY quantityInStock DESC
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS noOfQuantitys_sum
FROM s_products
ORDER BY productLine, quantityInStock desc
이번엔 productLine별로 전체적으로 집계하는 것이 아닌, 누적 집계를 보는 것이기에 UNBOUNDED PRECEDING부터 CURRENT ROW(현재행)까지 범위를 설정하면 된다.
WITH temp AS
(
SELECT CONCAT(firstName, ' ', lastName) AS 성명,
jobTitle AS 직책,
COALESCE(SUM(amount),0) AS 매출액
FROM s_employees
LEFT JOIN s_customers ON employeeId = salesRepId /* 담당 고객이 없는 직원 포함 */
LEFT JOIN s_payments USING (customerId)
GROUP BY employeeId
)
SELECT 성명, 직책, 매출액,
CONCAT(매출액 - 100000, '~', 매출액 + 100000) AS '매출액 범위',
COUNT(매출액) OVER
(
ORDER BY 매출액 DESC
RANGE BETWEEN 100000 PRECEDING AND 100000 FOLLOWING
) AS '범위내 직원수'
FROM temp;
매출액 오차 100000 범위 내의 인원수를 구하기 위해 WINDOW 함수를 통해 SUM()함수를 적용했는데, 이때 논리적인 값의 범위를 적용해야해서 RANGE BETWEEN을 사용했다. 이때, ROW BETWEEN을 사용하면 오류가 난다.
3. 행순서관련함수
FIRST_VALUE() : 파티션의 프레임 내에서 첫번째 행의 FIRST_VALUE 기준 컬럼 값
LAST_VALUE() : 파티션의 프레임 내에서 마지막 행의 LAST_VALUE 기준 컬럼 값
LAG() : 파티션 내에서 현재 행에 뒤쳐진(lagging)행, 즉 앞 행의 LAG 기준 컬럼 값
LEAD() : 파티션 내에서 현재 행에 앞선(leading) 행, 즉 뒤 행의 LEAD 기준 컬럼 값
4. 그룹내 비율관련함수
PERCENT_RANK() : 전체 투플 개수에 대한, 순위의 누적 백분율 (0~1)
CUME_DIST() : 순위를 기준으로 한, 투플 개수의 누적 백분율 (0~1)
PERCENT_RANK() 와 CUME_DIST()의 차이 : 전자는 전체 개수를 기준으로 하기에 1위는 0으로 출력 되지만 후자는 순위를 기준으로 하기에 1위의 데이터가 (1/전체 투플 개수 +1) 값으로 0외의 수가 출력 된다.
NTILE() : 파티션을 N개 버킷으로 분할한다. ex. 5개의 데이터가 있다면 1/1/2/2/3으로 분리
'DATA PROGRAMMING > SQL' 카테고리의 다른 글
[SQL] SQL 서브쿼리 총정리 (0) | 2023.09.06 |
---|---|
[SQL] 그룹함수 총정리 (0) | 2023.09.05 |
[SQL] 표준 SQL의 조인 연산 - FROM절 JOIN, 재귀 JOIN (0) | 2023.09.02 |
[SQL] 표준 SQL의 조인 연산 - WHERE절 조인 (0) | 2023.09.01 |
[SQL] sql tip - count함수를 활용하여 NULL값 처리하기 (0) | 2023.09.01 |