본문 바로가기

[LeetCode] 601. Human Traffic of Stadium

by qwee0328 2025. 4. 18.

📝 601. Human Traffic of Stadium

🔹 경기장의 인적 트래픽

연속된 ID를 가진 세 개 이상의 행이 있고, 각 행의 인원이 100명 이상인 레코드를 표시하는 솔루션을 작성하세요. visit_date를 기준으로 오름차순으로 정렬된 결과 테이블을 반환하세요.

 

 

 

📝 문제 설명

조건은 다음과 같습니다:

  • people이 100명 이상인 행만 고려
  • ID 기준으로 연속된 3개 이상의 행을 추출
  • 결과는 visit_date 기준 오름차순 정렬

 

📊 테이블 구조

Stadium 테이블

Column Name Type
id int
visit_date date
people int

 

 

 

💡 SQL 문제 해결 방법

이 문제는 연속된 행을 찾아내야 하므로, 일반적인 GROUP BY로는 해결이 어렵습니다.
윈도우 함수와 누적 그룹핑 기법을 활용하는 것이 핵심입니다.

  1. 먼저, people >= 100 조건을 만족하는 행만 필터링
  2. LAG() 함수를 이용해 이전 행의 ID와 비교 → 연속 여부 판단
  3. 연속되지 않은 지점에서 새로운 그룹을 시작하는 방식으로 그룹핑
  4. 각 그룹별로 COUNT(id) ≥ 3인 그룹만 추출
  5. 해당 그룹에 속하는 모든 행을 결과로 반환

 

 

🖥️ SQL 풀이

  SELECT id
       , visit_date
       , people
    FROM (
           SELECT *
                , COUNT(id) OVER (PARTITION BY grp) AS ysno_code
             FROM (
                    SELECT *
                         , SUM(continuity) OVER (ORDER BY id) AS grp
                      FROM (
                             SELECT *
                                  , CASE WHEN id = LAG(id) OVER (ORDER BY id) + 1 THEN 0 ELSE 1 END AS continuity
                               FROM Stadium
                              WHERE people >= 100
                           ) sub1
                  ) sub2
         ) sub3
   WHERE ysno_code >= 3
ORDER BY visit_date;

 

 

 

🔍 쿼리 분석

  • WHERE people >= 100: 100명 이상 조건 먼저 필터링
  • LAG(id) + CASE WHEN: 이전 행과의 id 차이를 비교해 연속 여부 판단
  • SUM(continuity) OVER (...): 연속된 구간마다 고유 그룹 번호 부여
  • COUNT(id) OVER (PARTITION BY grp): 각 그룹의 행 개수 계산
  • WHERE ysno_code >= 3: 3개 이상 연속된 그룹만 필터링

 

 

📌 실행 예제

📊 입력 데이터

Stadium 테이블

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

 

쿼리 실행 결과

id visit_date people
5 2017-01-05 145
6 2017-01-06 1455
7 2017-01-07 199
8 2017-01-09 188

 

 

📌 보충설명

✅ Step 1: WHERE people >= 100

id visit_date people
2 2017-01-02 109
3 2017-01-03 150
5 2017-01-05 145
6 2017-01-06 1455
7 2017-01-07 199
8 2017-01-09 188

 

 

✅ Step 2: LAG(id) + CASE WHEN → continuity 계산

  • id가 연속되는지 확인해서 연속이면 0, 끊기면 1
id visit_date people lag(id) continuity
2 2017-01-02 109 null 1
3 2017-01-03 150 2 0
5 2017-01-05 145 3 1
6 2017-01-06 1455 5 0
7 2017-01-07 199 6 0
8 2017-01-09 188 7 0

 

  • 연속되는 구간: 2-3, 5-6-7-8
  • id 4는 제외된 상태 (people < 100)

✅ Step 3: SUM(continuity) OVER (ORDER BY id) → 그룹핑

  • continuity = 1일 때 새로운 그룹 시작. SUM() 누적으로 그룹 번호 생성.
id visit_date people continuity grp
2 2017-01-02 109 1 1
3 2017-01-03 150 0 1
5 2017-01-05 145 1 2
6 2017-01-06 1455 0 2
7 2017-01-07 199 0 2
8 2017-01-09 188 0 2
  • 그룹 1: 2-3
  • 그룹 2: 5-6-7-8

✅ Step 4: COUNT(id) OVER (PARTITION BY grp) → 그룹 내 행 개수

id visit_date people grp ysno_code
2 2017-01-02 109 1 2
3 2017-01-03 150 1 2
5 2017-01-05 145 2 4
6 2017-01-06 1455 2 4
7 2017-01-07 199 2 4
8 2017-01-09 188 2 4

 

✅ Step 5: WHERE ysno_code >= 3 → 3개 이상인 그룹만 필터링

id visit_date people
5 2017-01-05 145
6 2017-01-06 1455
7 2017-01-07 199
8 2017-01-09 188

 

 

 

🎯 결론

이 문제는 LAG(), SUM() OVER, COUNT() OVER 같은 윈도우 함수를 복합적으로 활용하는 고급 SQL 문제입니다.

특히 연속된 조건을 만족하는 그룹핑 로직은,
👉 출석 연속일 계산, 구매 패턴 분석, 이탈 시점 분석 등 다양한 실무에도 응용될 수 있어요!

윈도우 함수누적 그룹핑 로직을 익혀두면, 데이터 분석 능력도 한층 더 올라갑니다 😊

 

 


 

 

 

더 많은 SQL 문제 풀이를 보고 싶다면 LeetCode SQL 문제 모음을 확인해 보세요! 🚀

728x90
반응형

'LeetCode' 카테고리의 다른 글

[LeetCode] 262. Trips and Users  (2) 2025.04.18
[LeetCode] 1393. Capital Gain/Loss  (0) 2025.04.17
[LeetCode] 1158. Market Analysis 1  (0) 2025.04.16
[LeetCode] 608. Tree Node  (0) 2025.04.16
[LeetCode] 184. Department Highest Salary  (0) 2025.03.26