@ddukbbok_kang

하고 싶은 건 일단 해봅니다.

SQL/LeetCode

[LeetCode Medium] 180. Consecutive Numbers(Lead, Lag 함수)(MySQL)

강떡볶 2023. 8. 24. 03:44

✅ 본 게시글은 학습 목적으로 LeetCode 문제의 풀이과정을 정리한 것이며, 모든 자료의 출처는 LeetCode에 있습니다.

 

Consecutive Numbers - LeetCode

Can you solve this real interview question? Consecutive Numbers - Table: Logs +-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | num | varchar | +-------------+---------+ In SQL, id is the primary key for this table.

leetcode.com

 

LeetCode Medium 문제를 풀면서 '어 좀 쉬운데?' 했다가 이 문제를 보고 조금 애를 먹었다 ㅠㅠ

그래도 포기하지 않고 끝까지 고민하니 풀이과정의 99%는 맞았는데, 틀린 1%를 위해 게시글을 작성한다. 

 


 

LeetCode 180번 문제

 

num 열에 있는 숫자가 연속으로 세 번 이상 나오면, 그 숫자를 출력하는 문제이다.

처음에는 row_number() over(partition by num) 요런식으로 접근했는데, 그렇게 하면 연속되지 않아도 카운트가 되어서 잘못된 방법이다.

그래서 '연속으로'라는 개념이 행과 관련이 있을 것 같아서 행을 서로 참조하는 함수가 뭐가 있을까.. 생각하다가 LAG와 LEAD 함수를 떠올리게 되었다.

 

 

1. LAG 함수

 

출처 : https://www.youtube.com/watch?v=j2u52RQ0qlw

LAG 함수는 현재 행을 기준으로 이전 행의 데이터에 접근할 수 있는 함수이다. 위 사진은 LAG(car_rentals) OVER(ORDER BY date_id) as previous_day 라고 작성했을 때 출력되는 결과이다. 사진에서 볼 수 있다시피, previous_day 컬럼의 1280이, LAG()의 괄호 안에 넣은 컬럼(car_rentals)의 하나 이전 행의 값임을 알 수 있다.

두 개 이전 행의 값을 출력하고 싶으면 LAG(car_rentals, 2)로 작성할 수 있다.

 

 

2. LEAD 함수

출처 : https://www.youtube.com/watch?v=j2u52RQ0qlw

LEAD 함수는 LAG 함수와 반대로, 현재 행을 기준으로 이후 행의 데이터에 접근할 수 있는 함수이다.

사진을 바탕으로 이해하면 그렇게 어려운 개념은 아니므로, LEAD 함수에 대한 자세한 설명은 생략하겠다.

 

 

내가 작성한 코드는 다음과 같다.

WITH lead_tbl AS
(SELECT num
        , LEAD(num, 1) OVER(ORDER BY id) AS lead_1
        , LEAD(num, 2) OVER(ORDER BY id) AS lead_2
FROM logs)

SELECT DISTINCT num AS ConsecutiveNums
FROM lead_tbl
WHERE num = lead_1 AND lead_1 = lead_2;

 

with 문으로 작성한 테이블의 결과를 출력하면 다음과 같다.

이렇게 리드함수를 활용해 num열의 값을 하나씩 위로 끌어당겨서 LEAD_1 열에 저장하고, num열의 값을 두 개씩 위로 끌어당겨서 LEAD_2 열에 저장한다. 그렇게 하면, 숫자가 연속으로 세 번 등장할 경우 num열과 LEAD_1, LEAD_2 열의 값이 같아지게 된다.

앞서 내가 1% 틀렸다는 게 바로 이 부분이다. WHERE num = lead_1 AND lead_1 = lead_2라고 작성해야 하는데,
WHERE num = lead_1 = lead_2라고 작성해서 계속 오류가 났다 ㅠㅠ 그래도 이 기회에 하나 배웠다.

위의 예시에서 num열을 보면 1만 연속으로 세 번 등장하는데, num열과 LEAD_1, LEAD_2 세 열의 값이 동일한 것 또한 1밖에 없다.
이 내용이 바로 WITH문 하단에 있는 쿼리의 WHERE 절의 내용이다. 그 후에 SELECT를 통해 num행의 고유값들을 출력해주면 끝!

최종적으로 다음과 같이 출력된다.