날짜 자르기와 구간화
DATE_TRUNC 및 이에 해당하는 기능으로 주, 월, 분기별로 그룹화합니다.
날짜 자르기와 구간화은(는) CoddyKit의 무료 Coding Interview Prep 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Coding Interview Prep 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
날짜를 구간화하는 이유
"주별 매출을 보여 주세요" 또는 "월별 활성 사용자를 보여 주세요"는 분석가 면접에서 가장 자주 나오는 질문입니다. 평가하는 역량은 정확한 타임스탬프를 더 거친 구간으로 축약하여 행들이 함께 그룹화되도록 만드는 것입니다.
초보자가 흔히 하는 실수는 월 번호만 추출하는 것입니다. 그러면 서로 다른 연도의 같은 달이 합쳐집니다. 전문적인 답변은 절단입니다. 모든 타임스탬프를 해당 기간의 시작 시점으로 매핑하는 방식입니다.
- 주, 월, 분기, 연도 구간
DATE_TRUNC및 방언별 대응 함수- 차트가 올바르게 정렬되도록 그룹화하기
DATE_TRUNC: 핵심 도구
PostgreSQL에서 DATE_TRUNC(unit, ts)는 지정한 단위보다 더 세밀한 부분을 모두 0으로 만듭니다. 'month'로 절단하면 3월의 어떤 타임스탬프든 2024-03-01 00:00:00으로 바뀝니다.
반환값은 여전히 타임스탬프이므로 시간순으로 정렬되고 완벽하게 그룹화됩니다. 이는 보고서 작성에 가장 유용한 단일 날짜 함수입니다.
SELECT DATE_TRUNC('month', TIMESTAMP '2024-03-17 14:30:00');
-- 2024-03-01 00:00:00월별 매출 그룹화
대표적인 실습 예제입니다. 타임스탬프를 월 단위로 절단한 다음 그룹화하고 합계를 구합니다. 구간에 연도가 포함되므로 2023년 1월과 2024년 1월은 서로 분리된 상태로 유지됩니다.
절단된 값을 기준으로 정렬하면 차트에 바로 사용할 수 있는 깔끔한 시계열이 만들어집니다.
SELECT
DATE_TRUNC('month', order_ts) AS month,
SUM(amount) AS revenue
FROM orders
GROUP BY 1
ORDER BY 1;EXTRACT와 DATE_TRUNC 비교
면접관은 이 차이를 직접 질문하는 경우가 많습니다. 두 함수 모두 기간 정보를 가져오지만, 서로 다른 질문에 답합니다.
EXTRACT(MONTH FROM ts)는 모든 연도의 3월에 대해 숫자 3을 반환하므로 계절성을 분석할 때 유용합니다.DATE_TRUNC('month', ts)는 특정 월의 시작 시점을 반환하여 연도를 구분하므로 시계열에 유용합니다.
월별 추세 차트에서 EXTRACT(MONTH ...)로 그룹화하면 연도들이 조용히 합쳐집니다.
-- Seasonality: which month is busiest on average?
SELECT EXTRACT(MONTH FROM order_ts) AS month_num, COUNT(*)
FROM orders GROUP BY 1 ORDER BY 1;
-- Time series: month-by-month trend (years kept separate)
SELECT DATE_TRUNC('month', order_ts) AS month, COUNT(*)
FROM orders GROUP BY 1 ORDER BY 1;주 구간과 월요일 기준 문제
주별 그룹화에는 면접관이 즐겨 묻는 미묘한 문제가 있습니다. 한 주는 언제 시작할까요? PostgreSQL의 DATE_TRUNC('week', ts)는 항상 월요일(ISO 주)로 맞춥니다.
업무에서 일요일 시작 주를 원한다면 날짜를 보정해야 합니다. 흔히 날짜를 하루 앞당긴 뒤 절단하고, 다시 하루를 더하는 방법을 사용합니다.
-- ISO week (Monday start)
SELECT DATE_TRUNC('week', order_ts) AS iso_week FROM orders;
-- Sunday-start week
SELECT DATE_TRUNC('week', order_ts + INTERVAL '1 day') - INTERVAL '1 day'
AS sunday_week
FROM orders;분기 구간
분기별 보고서는 금융 관련 직무에서 흔히 사용됩니다. DATE_TRUNC('quarter', ts)는 모든 타임스탬프를 해당 분기의 첫날인 1월 1일, 4월 1일, 7월 1일 또는 10월 1일로 매핑합니다.
대신 분기를 숫자로 표시하려면 EXTRACT(QUARTER ...)와 연도를 조합하십시오.
SELECT
DATE_TRUNC('quarter', order_ts) AS quarter_start,
EXTRACT(YEAR FROM order_ts) || '-Q'
|| EXTRACT(QUARTER FROM order_ts) AS quarter_label,
SUM(amount) AS revenue
FROM orders
GROUP BY 1, 2
ORDER BY 1;MySQL에는 DATE_TRUNC가 없습니다
방언을 넘나드는 질문으로 자주 나오는 예입니다. "MySQL에는 DATE_TRUNC가 없는데, 월별로 어떻게 구간화하나요?" 이식성 있는 답변은 원하는 세분성까지 날짜 형식을 지정하는 것입니다.
DATE_FORMAT(ts, '%Y-%m-01')은 월의 시작을 텍스트 또는 날짜로 제공합니다.DATE_FORMAT(ts, '%Y-%m')은2024-03과 같은 정렬 가능한 문자열 키를 제공합니다.
주 단위로는 MySQL의 YEARWEEK()에 주 시작일을 제어하는 모드 인수를 지정할 수 있습니다.
-- MySQL month bucket
SELECT DATE_FORMAT(order_ts, '%Y-%m-01') AS month, SUM(amount)
FROM orders
GROUP BY 1
ORDER BY 1;SQL 서버의 구간화
SQL 서버에는 역사적으로 직접 절단하는 기능이 없었기 때문에, 지원자들은 DATEFROMPARTS 또는 DATEADD/DATEDIFF 관용구를 사용했습니다. 최신 버전(2022 이상)에는 DATETRUNC이 추가되었습니다.
고전적인 관용구인 "기준 시점 이후의 단위 수를 센 다음, 그 수만큼 다시 더하기"는 모든 버전에서 작동하므로 알아 둘 가치가 있습니다.
-- Portable SQL Server month truncation
SELECT DATEADD(month, DATEDIFF(month, 0, order_ts), 0) AS month_start
FROM orders;
-- SQL Server 2022+
SELECT DATETRUNC(month, order_ts) AS month_start FROM orders;시계열의 빈 구간 채우기
절단만 사용하면 행이 0개인 기간이 사라집니다. 주문이 하나도 없는 달은 결과에 단순히 나타나지 않습니다. 면접관은 이 문제를 알아차리는지 확인합니다.
해결 방법은 모든 기간으로 구성된 완전한 축을 생성한 뒤 데이터에 LEFT JOIN하는 것입니다. PostgreSQL에서는 generate_series로 이 축을 만들 수 있습니다.
SELECT
cal.month,
COALESCE(SUM(o.amount), 0) AS revenue
FROM generate_series(DATE '2024-01-01', DATE '2024-12-01',
INTERVAL '1 month') AS cal(month)
LEFT JOIN orders o
ON DATE_TRUNC('month', o.order_ts) = cal.month
GROUP BY cal.month
ORDER BY cal.month;더 깊이 있는 예제: 주별 활성 사용자
구간화와 고유 개수 세기를 함께 사용해 보겠습니다. "주별 활성 사용자"는 실제 제품 분석에서 자주 나오는 요구 사항으로, 주 구간별 고유 사용자 수를 의미합니다.
이벤트 타임스탬프를 주 단위로 절단한 다음 COUNT(DISTINCT user_id)를 사용합니다. 활동이 없는 주도 표시하려면 주 단위 축을 조인하겠다고 언급하면 추가 점수를 얻을 수 있습니다.
SELECT
DATE_TRUNC('week', event_ts) AS week,
COUNT(DISTINCT user_id) AS wau
FROM events
GROUP BY 1
ORDER BY 1;인덱스가 있는 열의 구간화
언급할 만한 성능상의 주의점이 하나 있습니다. WHERE 절 안에서 날짜 열을 DATE_TRUNC로 감싸면 계획기가 해당 열의 인덱스를 사용하지 못할 수 있습니다.
GROUP BY에서는 괜찮지만, 필터링할 때는 계산한 경계를 기준으로 원래 열을 비교하십시오. 앞에서 다룬 반열린 구간 패턴이 여기에도 적용됩니다.
-- Avoid in WHERE: DATE_TRUNC('month', order_ts) = '2024-03-01'
-- Prefer:
SELECT * FROM orders
WHERE order_ts >= DATE '2024-03-01'
AND order_ts < DATE '2024-04-01';빠른 확인
연도를 서로 구분하는 월별 추세 차트에 적합한 도구를 고르십시오.
복습: 날짜 절단과 구간화
기억할 내용:
DATE_TRUNC(unit, ts)는 타임스탬프를 기간의 시작 시점으로 매핑하고 연도를 구분하므로 시계열에 적합한 도구입니다.EXTRACT는 숫자 하나만 반환하므로 계절성에는 좋지만 연도들이 합쳐집니다.- PostgreSQL의 주는 월요일에 시작합니다. 일요일이 필요하면 보정하십시오.
- MySQL은
DATE_FORMAT을 사용하고, 이전 SQL 서버 버전은DATEADD(DATEDIFF(...))관용구를 사용합니다. 2022 이상 버전에는DATETRUNC이 있습니다. - 빈 기간을 표시하려면 생성한 날짜 축 + LEFT JOIN을 사용하고, 인덱스 사용을 유지하려면
WHERE에서DATE_TRUNC을 사용하지 마십시오.
자주 묻는 질문
“날짜 자르기와 구간화” 강의는 무료인가요?
네 — “날짜 자르기와 구간화” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Coding Interview Prep 강의 전체를 잠금 해제할 수 있습니다. Coding Interview Prep 강의에는 총 4개의 강의가 포함되어 있습니다.
“날짜 자르기와 구간화”에서 뭘 배우나요?
DATE_TRUNC 및 이에 해당하는 기능으로 주, 월, 분기별로 그룹화합니다. 브라우저에서 직접 실행하는 실습 코드로 Coding Interview Prep을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Coding Interview Prep을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Coding Interview Prep은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“날짜 자르기와 구간화” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Coding Interview Prep 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Coding Interview Prep 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 날짜 연산과 간격
- 날짜 자르기와 구간화
- 문자열 파싱과 서식 지정
- 시간대와 타임스탬프