PostgreSQL집계와 분석

date_trunc와 generate_series

시간 구간별 집계와 빠진 날짜 채우기에서 자주 쓰는 `date_trunc`와 `generate_series` 패턴을 정리합니다.

마지막 수정 2026년 3월 22일

기본 패턴

sql
SELECT
  date_trunc('day', created_at) AS day,
  COUNT(*) AS count
FROM orders
GROUP BY 1
ORDER BY 1;

설명

  • date_trunc는 timestamp를 일, 주, 월 같은 일정한 단위로 잘라 같은 버킷에 묶게 해 줍니다. 시간대별·일별·월별 리포트에서 거의 기본처럼 쓰입니다.
  • generate_series는 연속된 숫자나 날짜 구간을 가상 테이블처럼 만들어 줍니다. 그래서 "기록이 없는 날짜도 0으로 채운 보고서" 같은 요구를 처리할 때 특히 강합니다.
  • 이 둘을 함께 쓰면 단순 집계를 넘어 시계열 리포트 구조를 꽤 정교하게 만들 수 있습니다. 예를 들어 최근 30일 날짜 목록을 먼저 만들고, 실제 주문 집계를 left join해 빈 날짜를 채울 수 있습니다.
  • 중요한 것은 리포트에서 "없는 날짜"도 데이터라는 감각입니다. 실제 행이 없는 날을 그냥 빼면 그래프와 정산표가 왜곡될 수 있습니다.
  • PostgreSQL은 이런 시계열 보조 작업을 애플리케이션 코드 바깥, SQL 안에서 상당 부분 처리할 수 있습니다. 그래서 데이터 팀과 백엔드가 같은 쿼리 언어로 대화하기 쉬워집니다.

빠른 정리

함수역할
date_trunc('day', ts)시간을 일 단위로 자르기
date_trunc('month', ts)시간을 월 단위로 자르기
generate_series(...)연속 구간 생성
잘 맞는 곳일별/월별 리포트, 빈 날짜 채우기

주의할 점

리포트 쿼리에서 실제 데이터만 GROUP BY하면 값이 없는 날짜는 통째로 사라집니다. 시계열 보고서라면 "없는 날짜를 어떻게 표현할지"를 먼저 정하고 쿼리를 짜는 편이 좋습니다.

참고 링크

2 sources