조건을 충족하는 N개의 연속 행
매출이 X를 초과하는 날이 3일 연속인 경우를 다루는 고전적인 윈도 패턴입니다.
조건을 충족하는 N개의 연속 행은(는) CoddyKit의 무료 Coding Interview Prep 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Coding Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
LeetCode 대표 문제
이 문제는 SQL 면접에서 가장 자주 출제되는 문제 중 하나입니다. "매출이 임계값을 초과한 날짜 중 최소 3일 연속인 모든 날짜를 찾으십시오." 또는 LeetCode에서 자주 다루는 "출석 인원이 100명을 초과하는 행이 3개 이상 연속된 경기장을 보고하십시오."와 같은 문제입니다.
형태는 항상 같습니다. 행은 N개의 조건 충족 행이 연속된 구간 안에 있을 때만 조건을 충족합니다. 이 단원에서는 깔끔한 두 가지 해결책과 대부분의 지원자를 잡아내는 함정을 보여 드립니다.
샘플 데이터
매일의 sales 테이블을 사용합니다. 조건은 amount > 100입니다. 조건을 모두 충족하는 3일 이상의 달력상 연속 날짜 구간에 속한 모든 날짜를 반환해야 합니다.
sale_date— 하루에 한 행amount— 해당 날짜의 총매출
핵심적인 세부 사항은 다음과 같습니다. 행은 순서상 연속이어야 하며, 날짜 기반 버전에서는 달력상으로도 연속이어야 합니다.
SELECT * FROM sales ORDER BY sale_date;
-- sale_date | amount
-- 2024-03-01 | 120
-- 2024-03-02 | 150
-- 2024-03-03 | 130
-- 2024-03-04 | 90
-- 2024-03-05 | 200접근법 1: 필터링 후 구간화
가장 안정적인 접근법은 먼저 조건을 충족하는 행만 남기고, 남은 행을 연속 구간으로 그룹화한 다음, 길이가 N 이상인 구간만 남기는 것입니다.
첫 단계는 WHERE 필터입니다. 두 번째 단계에서는 간격과 구간 앵커를 다시 사용합니다. 먼저 필터링했으므로 여기서 구간은 "조건을 충족하는 날짜가 연속된 구간"을 의미합니다.
WITH qualifying AS (
SELECT sale_date
FROM sales
WHERE amount > 100
)
SELECT * FROM qualifying ORDER BY sale_date;조건 충족 구간의 앵커 설정
조건을 충족하는 행에 날짜순으로 번호를 매기고 차이를 계산하여 구간 앵커를 얻습니다. 달력에서 연속이고 AND 모두 조건을 충족하는 행은 같은 앵커를 공유합니다. 조건을 충족하지 않는 날짜는 제거되므로, 연속 구간은 정확히 끊겨야 하는 지점에서 끊깁니다.
WITH qualifying AS (
SELECT sale_date
FROM sales
WHERE amount > 100
),
numbered AS (
SELECT sale_date,
ROW_NUMBER() OVER (ORDER BY sale_date) AS rn
FROM qualifying
)
SELECT sale_date, sale_date - rn AS grp
FROM numbered;충분히 긴 구간만 유지
앵커별로 그룹화하고 행을 센 다음, COUNT(*) >= 3인 그룹만 남깁니다. 면접관이 조건을 충족하는 개별 날짜를 다시 요구한다면, 남겨 둔 앵커를 번호가 매겨진 행에 조인합니다.
WITH qualifying AS (
SELECT sale_date FROM sales WHERE amount > 100
),
numbered AS (
SELECT sale_date,
ROW_NUMBER() OVER (ORDER BY sale_date) AS rn
FROM qualifying
),
islands AS (
SELECT sale_date - rn AS grp, COUNT(*) AS len
FROM numbered
GROUP BY sale_date - rn
HAVING COUNT(*) >= 3
)
SELECT n.sale_date
FROM numbered n
JOIN islands i ON n.sale_date - n.rn = i.grp
ORDER BY n.sale_date;접근법 2: 이동 COUNT 윈도
N이 작고 고정되어 있을 때 사용할 수 있는 더 세련된 접근법은 윈도 프레임을 사용하여 주변 행 중 조건을 충족하는 행의 수를 세는 것입니다. 이 행을 포함하는 N개의 연속 행 윈도 중 하나라도 모두 조건을 충족하면 해당 행은 결과에 포함됩니다.
먼저 참/거짓 표시를 추가한 다음, 이동 프레임에 걸쳐 그 표시를 합산합니다.
SELECT sale_date, amount,
CASE WHEN amount > 100 THEN 1 ELSE 0 END AS ok
FROM sales;세 프레임에 걸쳐 합산
정확히 3개의 행으로 이루어진 구간에서는, 여기서 끝나는 3행 윈도, 여기를 중심으로 하는 윈도, 여기서 시작하는 윈도 중 하나의 합이 3이면 조건을 충족하는 행이 결과에 포함됩니다. 세 개의 이동 합계를 계산하고 그중 하나라도 3인지 검사합니다.
이것이 LeetCode 601(경기장 인원 통행) 해결책의 핵심 기법입니다.
WITH flagged AS (
SELECT sale_date, amount,
CASE WHEN amount > 100 THEN 1 ELSE 0 END AS ok
FROM sales
),
w AS (
SELECT *,
SUM(ok) OVER (ORDER BY sale_date
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS s_end,
SUM(ok) OVER (ORDER BY sale_date
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS s_mid,
SUM(ok) OVER (ORDER BY sale_date
ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING) AS s_start
FROM flagged
)
SELECT sale_date, amount
FROM w
WHERE ok = 1 AND (s_end = 3 OR s_mid = 3 OR s_start = 3);달력 간격 함정
윈도 합계 방식은 ROWS를 사용하며, 인접한 결과 행을 세지 인접한 달력 날짜를 세지 않습니다. 조건을 충족하지 않는 날짜를 이미 필터링했다면, 두 행이 결과에서는 인접해 보여도 달력상으로는 연속되지 않을 수 있습니다.
교훈: 이동 윈도를 전체 일별 시계열에 적용하여 미리 필터링하지 않거나, 달력의 간격을 본질적으로 반영하는 날짜 앵커 방식을 사용하십시오. 면접에서는 이 절충점을 설명하십시오.
임의의 N으로 일반화하기
접근법 1(필터링 후 구간화)은 쉽게 일반화할 수 있습니다. HAVING COUNT(*) >= N만 변경하면 됩니다. N이 커질수록 더 많은 프레임이 필요한 여러 윈도 합계보다 이것이 큰 장점입니다.
매개변수화된 N이나 큰 N에는 구간 방식을 사용하십시오 — N−1개의 윈도를 직접 작성하는 대신 임계값 하나만 변경하면 됩니다.
-- only the threshold changes for N = 5
HAVING COUNT(*) >= 5접근법 선택
소리 내어 설명할 때 사용할 간단한 판단 기준은 다음과 같습니다.
- 필터링 후 구간화: 달력의 간격을 반영하고, 어떤 N으로도 일반화할 수 있으며, 전체 구간을 반환합니다 — 안전한 기본 선택입니다.
- 이동 윈도 합계: 밀도 높은 일별 시계열에서 작고 고정된 N에 우아하지만, ROWS와 달력의 차이에서 생기는 함정을 주의해야 합니다.
두 방법을 모두 언급한 다음 선택한 방법을 정당화하는 것이 중급에서 고급 수준의 면접관이 정확히 높이 평가하는 부분입니다.
전체 해결책
달력상 연속성을 보장하고 조건을 충족하는 날짜를 반환하는, 모든 N에 적용 가능한 이식성 높은 답변입니다.
WITH qualifying AS (
SELECT sale_date FROM sales WHERE amount > 100
),
numbered AS (
SELECT sale_date,
ROW_NUMBER() OVER (ORDER BY sale_date) AS rn
FROM qualifying
),
islands AS (
SELECT sale_date - rn AS grp, COUNT(*) AS len
FROM numbered
GROUP BY sale_date - rn
HAVING COUNT(*) >= 3
)
SELECT n.sale_date
FROM numbered n
JOIN islands i ON n.sale_date - n.rn = i.grp
ORDER BY n.sale_date;빠른 확인
미묘한 버그를 찾아보십시오.
복습
조건을 충족하는 N개의 연속 행을 찾으려면 다음과 같이 합니다.
- 필터링 후 구간화: 조건을 충족하는 행만 남기고,
date - ROW_NUMBER()로 앵커를 설정한 뒤 그룹화하고HAVING COUNT(*) >= N을 적용합니다. 일반화할 수 있고 달력의 간격도 반영합니다. - 이동 윈도 합계: 행에 표시를 추가하고 고정된 N행 프레임에 걸쳐 합산합니다. 우아하지만 미리 필터링한 데이터에서는 ROWS와 달력의 차이를 주의해야 합니다.
다음 주제: 오늘 기준 사용자의 현재 활성 연속 기록 계산
자주 묻는 질문
“조건을 충족하는 N개의 연속 행” 강의는 무료인가요?
네 — “조건을 충족하는 N개의 연속 행” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Coding Interview Prep 강의 전체를 잠금 해제할 수 있습니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
“조건을 충족하는 N개의 연속 행”에서 뭘 배우나요?
매출이 X를 초과하는 날이 3일 연속인 경우를 다루는 고전적인 윈도 패턴입니다. 브라우저에서 직접 실행하는 실습 코드로 Coding Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Coding Interview Prep을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Coding Interview Prep은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“조건을 충족하는 N개의 연속 행” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Coding Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Coding Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 연속된 달력 날짜 감지하기
- 사용자별 최장 연속 기록
- 조건을 충족하는 N개의 연속 행
- 오늘 기준 현재 활성 연속 기록