갭과 아일랜드 문제 인식하기
문제 설명에서 패턴을 식별하고 핵심 그룹화 관점을 익힙니다.
갭과 아일랜드 문제 인식하기은(는) CoddyKit의 무료 SQL Interview Prep 강의입니다. 이것은 4개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 SQL Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
면접관이 확인하는 패턴
시니어 면접관이 어떤 것의 연속 구간을 찾으라고 한다면, 이는 간격과 구간 문제를 보고 있는 것입니다. 이 이름은 다음과 같은 이미지에서 비롯되었습니다. 함께 속한 행은 구간을 이루고, 그 사이의 끊어진 부분은 간격을 이룹니다.
- 구간은 어떤 규칙에 따라 서로 인접한 행이 최대한 이어진 연속 구간입니다(연속된 정수, 연속된 날짜 또는 반복되는 동일한 상태 등).
- 간격은 두 구간 사이에 비어 있는 부분입니다.
이 문제 유형을 즉시 알아보는 것 자체가 시니어 수준의 신호입니다. 많은 지원자가 복잡한 자체 조인을 사용하지만, 우아한 답은 거의 항상 윈도 함수입니다.
구간을 숨기는 서술형 문제
어려운 점은 면접관이 간격과 구간이라는 표현을 거의 사용하지 않는다는 것입니다. 대신 다른 말로 숨깁니다. 다음과 같은 표현에 익숙해지십시오.
- "사용자가 계속 구독 중이었던 기간을 각각 찾으십시오."
- "서버가 며칠 연속으로 작동 상태를 유지했습니까?"
- "이 테이블에서 누락된 ID 범위는 무엇입니까?"
- "같은 상태의 인접한 행을 하나의 행으로 합치십시오."
이 모든 문제는 같은 구조입니다. 서로 붙어 있는 행을 그룹으로 묶은 다음, 그 그룹의 시작, 끝 또는 부재를 보고합니다. 표현을 구간으로 연결해 이해하면 SQL은 저절로 작성됩니다.
핵심 통찰: 그룹 키 만들기
전체 요령을 한 문장으로 요약하면 다음과 같습니다. 같은 구간에 속한 모든 행에 동일한 그룹 키를 부여할 수 있다면, 간단한 GROUP BY로 각 구간을 하나의 요약 행으로 합칠 수 있습니다.
따라서 모든 간격과 구간 문제에서 실제로 해야 할 일은 이 그룹 키를 계산하는 것입니다. 방식에 따라 계산법은 다르지만, 목표는 항상 같습니다. 키를 얻고 나면 마지막 단계는 간단합니다.
SELECT
grp,
MIN(value) AS island_start,
MAX(value) AS island_end,
COUNT(*) AS island_length
FROM rows_with_group_key
GROUP BY grp
ORDER BY island_start;구체적인 데이터 집합
데이터를 기준으로 살펴보겠습니다. 사용자가 로그인한 날짜 번호를 기록하는 logins 테이블을 생각해 보십시오.
- 존재하는 날짜: 1, 2, 3, 7, 8, 10
눈으로 보면 구간은 {1,2,3}, {7,8}, {10}입니다. 간격은 4~6일과 9일입니다. 면접에서 해야 할 일은 직접 가리키지 않아도 데이터베이스가 이 세 구간을 알아보게 만드는 것입니다. 각 기법을 살펴보는 동안 이 작은 데이터 집합을 기억해 두십시오.
CREATE TABLE logins (day_no INT);
INSERT INTO logins VALUES (1),(2),(3),(7),(8),(10);단순한 접근 방식이 실패하는 이유
많은 사람이 처음에는 자체 조인으로 각 행을 다음 행과 비교해 단절을 표시하려고 합니다. 하나의 간격을 찾는 데는 효과적이지만 곧 다루기 어려워집니다.
- 각 구간의 시작과 끝을 모두 찾아야 하므로 두 번의 처리나 두 번의 조인이 필요합니다.
- 경계 행(정확히 첫 번째와 마지막 행)은 특별히 처리해야 합니다.
- 추가 장치 없이는 "모든 연속 구간의 길이를 알려 달라"는 요구로 확장하기 어렵습니다.
면접관은 지원자가 자체 조인을 복잡하게 이어 붙이는 방향으로 가는지, 아니면 윈도 함수 한 번으로 더 깔끔하게 해결할 수 있음을 알아보는지를 확인합니다.
간격 감지 사고방식
신뢰할 수 있는 접근 방식은 다음과 같습니다. 현재 행이 이전 행과 인접하지 않을 때마다 새 구간이 시작됩니다. LAG를 사용해 한 행 뒤를 살펴보고 비교하십시오.
day_no - LAG(day_no)가 1보다 크거나 첫 번째 행이라 NULL이면 해당 행이 새 구간의 시작입니다. 이를 표시값 1로 기록하고, 그렇지 않으면 0으로 기록합니다. 앞의 데이터에서 이 표시값이 어떻게 나타나는지 확인해 보십시오.
SELECT
day_no,
CASE
WHEN day_no - LAG(day_no) OVER (ORDER BY day_no) = 1 THEN 0
ELSE 1
END AS is_new_island
FROM logins
ORDER BY day_no;표시값을 그룹 키로 바꾸기
앞 단계에서 얻은 표시값은 날짜 1, 2, 3, 7, 8, 10에 대해 1, 0, 0, 1, 0, 1입니다. 이 표시값의 누적 합계를 계산하면 구간 안에서는 일정하게 유지되고 새 구간마다 증가하는 숫자가 된다는 점에 주목하십시오. 결과는 1,1,1,2,2,3입니다.
이 누적 합계가 직접 만든 그룹 키입니다. 표시값을 계산하는 쿼리를 CTE로 감싼 다음, 다른 윈도 함수로 합계를 계산합니다.
WITH flagged AS (
SELECT
day_no,
CASE WHEN day_no - LAG(day_no) OVER (ORDER BY day_no) = 1
THEN 0 ELSE 1 END AS is_new_island
FROM logins
)
SELECT
day_no,
SUM(is_new_island) OVER (ORDER BY day_no) AS grp
FROM flagged;예제 풀이 완성하기
이제 그룹 키 위에 최종 GROUP BY를 쌓으십시오. 서로 다른 grp 값 하나가 구간 하나를 나타내므로, 구간의 경계와 크기를 보고합니다.
결과는 눈으로 확인했던 세 구간과 정확히 같습니다. 1~3(길이 3), 7~8(길이 2), 10~10(길이 1)입니다. 이 세 단계의 방법(표시, 누적 합계, 그룹화)은 작성하게 될 거의 모든 간격과 구간 답변의 핵심 틀입니다.
WITH flagged AS (
SELECT day_no,
CASE WHEN day_no - LAG(day_no) OVER (ORDER BY day_no) = 1
THEN 0 ELSE 1 END AS is_new
FROM logins
),
keyed AS (
SELECT day_no,
SUM(is_new) OVER (ORDER BY day_no) AS grp
FROM flagged
)
SELECT grp, MIN(day_no) AS start_day,
MAX(day_no) AS end_day, COUNT(*) AS len
FROM keyed GROUP BY grp ORDER BY start_day;인접성은 도메인에 따라 다릅니다
문제마다 달라지는 유일한 부분은 인접의 정의입니다. 올바른 인접 규칙을 알아내는 것이 문제를 파악하는 일의 절반입니다.
- 정수: 차이가 정확히 1이면 인접합니다.
- 달력 날짜: 한 날짜가 다음 날짜이면 인접합니다(
date = prev + INTERVAL '1 day'). - 상태 기간: 이전 행과 상태 값이 같으면 인접합니다.
뼈대는 같고, CASE 안의 비교만 달라집니다. 어떤 인접 규칙을 적용해야 하는지 확인하는 것이 면접에서 소리 내어 물어야 할 명확화 질문입니다.
확인해야 할 질문
SQL 한 줄을 작성하기 전에 범위를 명확히 해 좋은 인상을 남기십시오. 간격과 구간 문제에서 유용한 확인 질문은 다음과 같습니다.
- "데이터를 사용자별로 처리해야 합니까, 아니면 전체를 한꺼번에 처리해야 합니까?" (이 질문에 따라
PARTITION BY user_id를 추가할지가 결정됩니다.) - "같은 날짜에 중복 값이 있을 수 있습니까? 중복 값이 연속 구간을 끊습니까, 아니면 연장합니까?"
- "구간을 원하십니까, 간격을 원하십니까, 아니면 둘 다 원하십니까?"
- "순서가 정렬되어 있다는 보장이 있습니까, 아니면 제가 직접 정렬해야 합니까?"
이러한 질문을 말로 확인하면 이 문제 유형을 이전에 해결해 보았고 경계 사례도 이해하고 있다는 인상을 줄 수 있습니다.
PARTITION BY를 사용한 그룹별 구간
실제 면접 데이터는 거의 항상 그룹으로 나뉘어 있습니다. 예를 들어 사용자별 로그인 데이터가 그렇습니다. 해결책은 간단합니다. 모든 윈도 함수에 PARTITION BY user_id를 추가해 구간이 사용자 사이의 경계를 넘지 않게 하십시오.
뼈대는 동일하고 파티션만 추가하면 됩니다. 먼저 단일 흐름의 경우를 익히는 것이 중요한 이유도 여기에 있습니다. 그룹별 처리로 확장하는 것은 절 하나를 바꾸는 일에 불과하기 때문입니다.
SELECT
user_id, day_no,
CASE WHEN day_no - LAG(day_no)
OVER (PARTITION BY user_id ORDER BY day_no) = 1
THEN 0 ELSE 1 END AS is_new
FROM logins;빠른 확인
패턴 인식 감각을 확인해 보십시오.
요약: 형태 파악하기
이제 문제의 표현에 숨은 간격과 구간 문제를 알아보고 전략을 설명할 수 있습니다.
- 핵심 단어: 연속, 지속, 끊김 없음, 연속 기록, 누락 범위, 인접 행 통합
- 핵심 아이디어: 같은 연속 구간의 모든 행에 동일한 그룹 키를 부여한 다음
GROUP BY로 그룹화합니다. - 방법:
LAG로 새 구간을 표시하고, 표시값의 누적 합계로 키를 만든 다음 집계합니다. - 인접성은 도메인에 따라 다릅니다(정수, 날짜 또는 변하지 않는 상태).
- 그룹별 분석에는
PARTITION BY를 추가하고, 코딩하기 전에 범위를 명확히 하십시오.
다음에서는 가장 우아한 키 생성 방법인 행 번호 차이 기법을 더 자세히 살펴보겠습니다.
자주 묻는 질문
“갭과 아일랜드 문제 인식하기” 강의는 무료인가요?
네 — “갭과 아일랜드 문제 인식하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 SQL Interview Prep 강의 전체를 잠금 해제할 수 있습니다. SQL Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
“갭과 아일랜드 문제 인식하기”에서 뭘 배우나요?
문제 설명에서 패턴을 식별하고 핵심 그룹화 관점을 익힙니다. 브라우저에서 직접 실행하는 실습 코드로 SQL Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
SQL Interview Prep을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 SQL Interview Prep은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 1번째 강의입니다.
“갭과 아일랜드 문제 인식하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 SQL Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 SQL Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 갭과 아일랜드 문제 인식하기
- 행 번호 차이 기법
- 계열에서 누락 구간 찾기
- 날짜와 상태 변화가 있는 아일랜드