230219, 230220
https://leetcode.com/problems/consecutive-numbers/
적어도 3번 연속으로 나오는 숫자 찾기
어렵다..
id = id+1 = id+2의 num
이렇게 풀면 되겠지 라고 생각은 했는데 어떻게 구현해야할지 모르겠다.
SELECT DISTINCT l.num AS ConsecutiveNums
FROM logs l
INNER JOIN logs l1 ON l.id + 1 = l1.id
INNER JOIN logs l2 ON l.id + 2 = l2.id
WHERE l.num = l1.num AND l.num = l2.num
아예 두 번째와 세 번째에 해당하는 값을 행으로 추가해 문제를 푼 것을 확인하였다.
l.id + 1 = l1.id
이게 잘 이해가 안 갔는데
Input:
Logs table:
id | num |
---|---|
1 | 1 |
2 | 1 |
3 | 1 |
4 | 2 |
5 | 1 |
6 | 2 |
7 | 2 |
input이 이럴 때 l.id + 1 = l1.id
로 join을 하게 되면
l.id | l.num | l1.id | l1.num |
---|---|---|---|
1 | 1 | 2 | 1 |
2 | 1 | 3 | 1 |
3 | 1 | 4 | 2 |
이와 같게 된다. 그래서 이걸 이용해 연속적인 숫자를 구할 수 있다.
다음에 이 문제 한 번 더 풀어야 할 듯 싶다
COUNT나 SUM 이용해서 하려고 했으나
SELECT id
, num
, COUNT(id) OVER (PARTITION BY num ORDER BY id) ConsecutiveNums
FROM Logs
ORDER BY id
이렇게 했을 경우
id | num | ConsecutiveNums |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 | 1 | 3 |
4 | 2 | 1 |
5 | 1 | 4 |
6 | 2 | 2 |
7 | 2 | 3 |
결과가 이렇게 나와서 떨어져있어도 num으로 그룹화했기 때문에 누적이 돼서 안되겠다 싶었다. 강의에서 들었던 두 번째와 세 번째 값을 새로 열로 만들어 푸는 수 밖에 없다 생각함.
WITH wind AS (
SELECT id
, num
, LEAD(num) OVER (ORDER BY id) le1
, LEAD(num, 2) OVER (ORDER BY id) le2
FROM Logs
)
SELECT DISTINCT num AS ConsecutiveNums
FROM wind
WHERE num = le1 and num = le2
작명 센스..ㅎ window 안 돼서 wind으로 함
이렇게 밖에 안되는데 이게 더 복잡한 느낌
SELECT DISTINCT num AS ConsecutiveNums
FROM (
SELECT num
, LEAD(num) OVER (ORDER BY id) le1
, LEAD(num, 2) OVER (ORDER BY id) le2
FROM Logs
) l
WHERE num = le1 and num = le2
with문에 해당하는 것을 from 절 서브쿼리에 넣어 사용.
만약 LEAD 대신 LAG를 사용한다면
SELECT DISTINCT num AS ConsecutiveNums
FROM (
SELECT num
, LAG(num) OVER (ORDER BY id) le1
, LAG(num, 2) OVER (ORDER BY id) le2
FROM Logs
) l
WHERE num = le1 and num = le2
LEAD를 LAG로만 변경하면 된다. 그럼
num | le1 | le2 |
---|---|---|
1 | null | null |
1 | 1 | null |
1 | 1 | 1 |
2 | 1 | 1 |
1 | 2 | 1 |
2 | 1 | 2 |
2 | 2 | 1 |
이렇게 세 번째 행에서 비교하겠지