홍동이의 성장일기
[LeetCode] 601. Human Traffic of Stadium (연속된 id 가져오기) 본문
리트코드에 무료로 나와있는 MEDIUM 레벨의 문제를 모두 해결해서
오늘부터는 HARD 레벨의 문제를 풀며 고급 SQL 문제를 복기 겸 연습해보겠습니다!
🔎 문제
📍 문제 링크: https://leetcode.com/problems/human-traffic-of-stadium/description/
연속된 ID를 가진 3개 이상의 행으로 레코드를 표시하는 솔루션을 작성하고, 각 행에 대해 100명 이상의 인원이 필요합니다. visit_date별로 주문한 결과표를 오름차순으로 반환합니다.
Example 1:
Input:
Stadium table:
+------+------------+-----------+
| id | visit_date | people |
+------+------------+-----------+
| 1 | 2017-01-01 | 10 |
| 2 | 2017-01-02 | 109 |
| 3 | 2017-01-03 | 150 |
| 4 | 2017-01-04 | 99 |
| 5 | 2017-01-05 | 145 |
| 6 | 2017-01-06 | 1455 |
| 7 | 2017-01-07 | 199 |
| 8 | 2017-01-09 | 188 |
+------+------------+-----------+
Output:
+------+------------+-----------+
| id | visit_date | people |
+------+------------+-----------+
| 5 | 2017-01-05 | 145 |
| 6 | 2017-01-06 | 1455 |
| 7 | 2017-01-07 | 199 |
| 8 | 2017-01-09 | 188 |
+------+------------+-----------+
ID가 5, 6, 7, 8인 4행은 연속 ID를 가지며 각각 >= 100명이 참석했습니다.
visit_date 7행의 다음 날이 아님에도 불구하고 8행이 포함되었습니다.
ID가 2와 3인 행은 최소 3개의 연속 ID가 필요하기 때문에 포함되지 않습니다.
💡 문제 풀이
WITH cte_1 AS(
SELECT *
, LAG(id, 2) OVER(ORDER BY id) as lag2_id
, LAG(id, 1) OVER(ORDER BY id) as lag_id
, LEAD(id, 1) OVER(ORDER BY id) as lead_id
, LEAD(id, 2) OVER(ORDER BY id) as lead2_id
FROM stadium
WHERE people >= 100
)
SELECT id, visit_date, people
FROM cte_1
WHERE (id+1=lead_id AND lead_id+1=lead2_id)
OR (id-1=lag_id AND id+1=lead_id)
OR (id-1=lag_id AND id-2=lag2_id)
1️⃣ 앞, 뒤로 2개의 id를 가져온다.
where절을 통해 people이 100 이상인 행만 가져온다.
2️⃣ id가 연속 3개인 행을 불러오기 위해서는 세 가지의 관계를 봐야 한다.
- id 뒤로 연속 두 개의 숫자가 있는 경우 (ex. 5,6,7)
- id가 중간인 상태로 연속한 id가 이어지는 경우 (ex. 6,7,8)
- id 앞으로 연속 두개의 숫자가 있는 경우 (ex. 6,7,8)
세 가지 중 하나라도 만족하면 결과값으로 출력되도록 한다.
🔎 Solutions
이건 soultions에 올라와있는 풀이방법이다. 중간에 끊기는 숫자가 생길 때마다 id_diff의 값이 달라지는 원리를 사용했다. 나중에 유사한 문제가 나오면 사용해 봐야겠다.
with q1
as (
select *
, id - row_number() over() as id_diff
from stadium
where people > 99
)
select id, visit_date, people
from q1
where id_diff in (select id_diff from q1 group by id_diff having count(*) > 2)
order by visit_date
1️⃣ row_number을 사용하여 각 행에 순번을 붙인다.
2️⃣ id에서 rou_number을 빼준 것을 id_diff로 이름 붙이고, id_diff를 기준으로 group by를 해주어 그 수가 2개 초과인 값을 불러온다.
'Tool > SQL 코딩테스트 풀이' 카테고리의 다른 글
[Advent of SQL 2024🎄] 정수 나눗셈, SELECT절 CASE문 (0) | 2024.12.23 |
---|---|
[Advent of SQL 2024🎄] SQLite 특수문자 포함하지 않도록 하는 구문 (0) | 2024.12.16 |
[LeetCode] 1934. Confirmation Rate (특정 조건에 부합하는 확률 구하기) (0) | 2024.03.18 |
[LeetCode] 1907. Count Salary Categories (범위에 값이 없으면 0을 반환) (1) | 2024.01.07 |
[LeetCode] 1341. Movie Rating (Union vs. Union All) (2) | 2024.01.03 |