Coding/SQL

[LeetCode-SQL 50] 180.Consecutive Numbers(윈도우 함수)

kangplay 2025. 1. 16. 19:27
문제

설명

지금까지 필터링할 때 쓴 문법은 WHERE, HAVING 이다. 하지만 WHERE나 HAVING은 행 단위로 적용이 되기 때문에, 연속으로 3번 등장한 NUM을 골라야하는 열 기반 적용은 다른 방향성을 가져야한다.

 

1. JOIN을 이용하여 행 단위로 수정하기

JOIN을 사용하면, 컬럼을 추가하여 컬럼 단위로 필터링을 할 수 있다.

하지만 JOIN은 테이블과 테이블을 곱하기 때문에 복잡도에서는 O(N^2)이라고 할 수 있다.

 

2. WINDOW 함수를 이용하기 

WINDOW 함수는 행과 행 간의 관계를 쉽게 정의하기 위해 만든 함수로, 랭킹 함수, 집계 함수, 행 순서 관련 함수, 비율 관련 함수 등 다양하다.

WINDOW FUNCTION 중에서 그룹 내 행 순서 관련 함수인 LAG 과 LEAD를 사용해보자.

LAG는 파티션별 윈도우에서 이전 몇 번째 행의 값을 가져올 수 있다.

반대로 LEAD는 파티션별 윈도우에서 이후 몇 번째의 행의 값을 가져올 수 있다.

WINDOW 함수는 컬럼을 하나 더 만드는 것이기 때문에 JOIN보다는 훨씬 더 적은 연산량으로 결과를 도출할 수 있다. 

구현
# JOIN문
SELECT DISTINCT l1.num AS ConsecutiveNums
    FROM Logs l1 
    JOIN Logs l2 ON (l1.id +1) = l2.id
    JOIN Logs l3 ON (l2.id +1) = l3.id 
    WHERE l1.num = l2.num and l2.num = l3.num

# LAG, LEAD 함수
SELECT DISTINCT A.num AS ConsecutiveNums
FROM ( SELECT *, LEAD(num,1) OVER (ORDER BY id) AS LEAD1, LEAD(num,2) OVER (ORDER BY id) AS LEAD2
        FROM Logs l1 ) A
WHERE A.num = A.LEAD1 and A.LEAD1 = A.LEAD2