✅ 본 게시글은 학습 목적으로 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%를 위해 게시글을 작성한다.
num 열에 있는 숫자가 연속으로 세 번 이상 나오면, 그 숫자를 출력하는 문제이다.
처음에는 row_number() over(partition by num) 요런식으로 접근했는데, 그렇게 하면 연속되지 않아도 카운트가 되어서 잘못된 방법이다.
그래서 '연속으로'라는 개념이 행과 관련이 있을 것 같아서 행을 서로 참조하는 함수가 뭐가 있을까.. 생각하다가 LAG와 LEAD 함수를 떠올리게 되었다.
1. LAG 함수
LAG 함수는 현재 행을 기준으로 이전 행의 데이터에 접근할 수 있는 함수이다. 위 사진은 LAG(car_rentals) OVER(ORDER BY date_id) as previous_day 라고 작성했을 때 출력되는 결과이다. 사진에서 볼 수 있다시피, previous_day 컬럼의 1280이, LAG()의 괄호 안에 넣은 컬럼(car_rentals)의 하나 이전 행의 값임을 알 수 있다.
두 개 이전 행의 값을 출력하고 싶으면 LAG(car_rentals, 2)로 작성할 수 있다.
2. LEAD 함수
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행의 고유값들을 출력해주면 끝!
최종적으로 다음과 같이 출력된다.
'SQL > LeetCode' 카테고리의 다른 글
[LeetCode Medium] 550. Game Play Analysis IV(MySQL) (2) | 2023.08.28 |
---|---|
[LeetCode Medium] 176. Second Highest Salary(MySQL) (0) | 2023.08.26 |