🏫 추가 학습 (Window Function)
참고로 OVER()는 윈도우 함수가 적용될 데이터 범위를 정하는 역할이다.
순위 함수 (Ranking Functions)
SELECT id, num,
ROW_NUMBER() OVER(ORDER BY num) AS row_num,
RANK() OVER(ORDER BY num) AS rank_num,
DENSE_RANK() OVER(ORDER BY num) AS dense_rank_num
FROM Logs;
- ROW_NUMBER()
- 정렬 순서대로 고유한 순위 부여 ( 동점 없음)
- 시간 복잡도 O(N log N)
- RANK()
- 같은 값이면 동일한 순위, 다음 순위는 건너 뜀
- 시간 복잡도 O(N log N)
- DENSE_RANK()
- 같은 값이면 동일한 순위, 다음 순위는 연속 됨
- 시간 복잡도 O(N log N)
이동 함수 (Value Fnuctions)
SELECT id, num,
LAG(num, 1) OVER(ORDER BY id) AS prev_num,
LEAD(num, 1) OVER(ORDER BY id) AS next_num
FROM Logs;
- LAG(columnm, n, default)
- 이전 n번째 행의 값을 가져옴
- O(N)
- LEAD(columnm, n, default)
- 다음 n번째 행의 값을 가져옴
- O(N)
- FIRST_VALUE(column)
- 윈도우 내 첫 번째 행의 값을 가져옴
- O(N
- LAST_VALUE(column)
- 윈도우 내 마지막 행의 값을 가져옴
- O(N
- NTH_VALUE(column, n)
- 윈도우 내 n번째 행의 값을 가져옴
- O(N)
집계 함수 (Aggregate Functions)
- SUM(column)
- AVG(column)
- COUNT(column)
- MIN(column)
- MAX(column)
Window Function 성능 최적화
- ORDER BY를 최소화하면 정렬 비용 절감 → 속도 향
- PARTITION BY를 사용하면 병렬 처리 가능 → 성능 향상
- PARTITION BY는 GROUP BY와 다르게 원본 행을 유지한다.
🗒️SQL 코드 풀이 1
SELECT DISTINCT L0.num AS ConsecutiveNums
FROM Logs L0
LEFT JOIN
(
SELECT id-1 AS id, num
FROM Logs
WHERE id-1 > 0
) L1
ON L0.id = L1.id
LEFT JOIN
(
SELECT id-2 AS id, num
FROM Logs
WHERE id-2 > 0
) L2
ON L0.id = L2.id
WHERE L0.num = L1.num AND L0.num = L2.num
1. SQL은 행 기반의 DB로 열을 비교할때는 행 기반으로 만들어줘야 한다.
2. 문제에서 3번 연속적이라고 주어져 있으니, 조건을 걸어 LEFT JOIN을 2번을 해준다.
- 첫번째 LEFT JOIN 에서는 id -1을 해줘서 JOIN
- 두번째 LEFT JOIN 에서는 id - 2를 해줘서 JOIN
3. 이렇게 만들 테이블을 WHERE 문으로 필터링하여 원하는 데이터 출력한다.
하지만 JOIN 연산의 비싼 연산이라고 한다.
이 문제를 Window Function으로도 간단하게 풀 수 있다.
🗒️SQL 코드 풀이 2
SELECT DISTINCT num AS ConsecutiveNums
FROM
(
SELECT *, LAG(num) OVER(ORDER BY id) AS num2 , LAG(num,2) OVER(ORDER BY id) AS num3
FROM Logs
) A
WHERE A.num = A.num2 AND A.num2 = A.num3
1, LAG 또는 LEAD 함수를 사용한다.
- 해당 함수로 이전 또는 이후값의 컬럼을 만들 수 잇다.
2. 새로운 컬럼을 만들 테이블을 가져와서 WHERE로 필터링 한다.
- WHERE 절의 순서는 SELECT 절 보다 먼저이므로 서브쿼리로 가져옴
📌 문제 코멘트
해당 문제를 포스팅하는 이유는 다음과 같다.
- 그동안 SUM, AVG, MIN 등 몇개를 제외한 Window Function 사용해보지 못함
- LAG, LEAD 함수로 훨씬 간단하게 풀제 풀이 (해당 함수를 처음 써봄)
- 항상 이런 문제 풀 때, 행 비교가 잘 안되서 답답했는데, 이렇게 간단하게 가능...
Window Function에 대해 배웠지만, 막상 실제 써야 할 때는 잘 모른다.
그러니까 문제를 많이 풀어보면서 익숙해져보자
📚문제
'♟️ 알고리즘 > Leetcode' 카테고리의 다른 글
[MySQL][Leet Code] 262. Trips and Users (Hard) (0) | 2025.03.08 |
---|---|
[MySQL][Leet Code] 185. Department Top Three Salaries (Hard) (0) | 2025.03.08 |
[MySQL][Leet Code] 1789. Primary Department for Each Employee (Easy) (0) | 2025.03.07 |
[MySQL][Leet Code] 619. Biggest Single Number (0) | 2025.03.05 |
[MySQL][Leet Code] 1070. Product Sales Analysis III (Medium) (0) | 2025.03.05 |