♟️ 알고리즘/Leetcode

[MySQL][Leet Code]180. Consecutive Numbers (Medium)

Jerry_K 2025. 3. 7. 13:00

https://leetcode.com/problems/consecutive-numbers/description/?envType=study-plan-v2&envId=top-sql-50


🏫  추가 학습 (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에 대해 배웠지만, 막상 실제 써야 할 때는 잘 모른다.

그러니까 문제를 많이 풀어보면서 익숙해져보자 


📚문제