BigQuery에서 GA4 세션 수 계산하는 SQL 방법
- 세션은 user_pseudo_id와 ga_session_id 조합으로 구분합니다.
- events_*와 _TABLE_SUFFIX로 조회 날짜를 제한합니다.
- 날짜별 집계와 세션 시작일 집계는 기준이 다릅니다.
BigQuery에서 GA4 세션 수를 계산하려면 이벤트 매개변수의 ga_session_id와 최상위 필드인 user_pseudo_id를 함께 묶어 고유 조합을 세면 됩니다. 세션 ID는 세션 시작 시점의 초 단위 타임스탬프로 생성되므로, 다른 사용자에게 같은 값이 생길 수 있습니다. 아래 SQL은 지정한 날짜 범위에 이벤트가 하나 이상 기록된 고유 세션을 계산합니다. 프로젝트 ID, 데이터세트, 날짜를 실제 값으로 바꿔 실행하세요. Google 애널리틱스 공식 안내에서 세션 ID 생성 방식과 세션 수 집계 차이를 확인할 수 있습니다.
세션 수 계산의 기준부터 확인하기

두 필드를 함께 세는 이유
ga_session_id는 세션 시작 시점의 초 단위 타임스탬프이므로 사용자 간에 같은 값이 생길 수 있습니다. 따라서 이 값만 세면 서로 다른 사용자의 세션을 하나로 합칠 위험이 있습니다. Google은 BigQuery 내보내기에서 고유 세션을 세는 표준 방식으로 user_pseudo_id와 ga_session_id의 조합을 안내합니다. Google Analytics의 고유 개수 근사값 안내에서도 이 조합을 설명합니다.
세션 시작 이벤트만 세지 않는 기본 쿼리
GA4 내보내기 데이터는 이벤트 단위로 저장됩니다. 한 세션에 여러 이벤트가 있으므로 행 개수를 세면 세션 수가 아니라 이벤트 수가 됩니다. 아래 쿼리는 각 이벤트의 세션 ID를 읽은 뒤 사용자와 세션 ID의 조합을 중복 제거해 계산합니다.
세션 키는 user_pseudo_id + ga_session_id입니다. 이벤트 행 수나 ga_session_id 단독 개수로 세션 수를 대신하지 마세요.
날짜 범위 전체 세션 수를 구하는 SQL

GA4 일일 내보내기 테이블은 보통 events_YYYYMMDD 형식입니다. 와일드카드 테이블 events_*에 날짜 접미사 조건인 _TABLE_SUFFIX를 적용하면 필요한 기간의 테이블을 조회할 수 있습니다. 아래 예시에서 2026년 10월 1일부터 10월 7일까지를 분석하려면 날짜 두 곳을 원하는 기간으로 수정하세요.
WITH event_sessions AS (
SELECT
user_pseudo_id,
(SELECT value.int_value
FROM UNNEST(event_params)
WHERE key = 'ga_session_id'
LIMIT 1) AS ga_session_id
FROM `프로젝트ID.데이터세트.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20261001' AND '20261007'
)
SELECT
COUNT(DISTINCT STRUCT(user_pseudo_id, ga_session_id)) AS session_count
FROM event_sessions
WHERE user_pseudo_id IS NOT NULL
AND ga_session_id IS NOT NULL;
UNNEST는 배열 형태인 event_params에서 원하는 매개변수를 찾는 데 사용합니다. 여기서는 상관 하위 쿼리로 세션 ID를 읽습니다. COUNT(DISTINCT STRUCT(...))는 두 필드의 조합을 중복 없이 집계합니다. GA4 내보내기 스키마는 Google Analytics BigQuery 내보내기 스키마에서, 매개변수 추출 및 날짜 범위 쿼리 예시는 Google Analytics 이벤트 데이터 기본 쿼리에서 확인할 수 있습니다.
실행 전 SQL을 설정하는 순서

1단계: 테이블 경로를 확인합니다
BigQuery 탐색기에서 GA4 데이터세트를 열고 테이블 ID를 확인합니다. 예시의 프로젝트ID.데이터세트를 실제 경로로 바꾸세요. GA4 속성과 BigQuery 연결 및 내보내기가 설정되어 있어야 이벤트 테이블이 생성됩니다.
2단계: 조회할 시작일과 종료일을 입력합니다
_TABLE_SUFFIX에는 YYYYMMDD 형식의 날짜를 입력합니다. BETWEEN은 양 끝 날짜를 포함합니다. 넓은 기간을 조회할수록 처리할 데이터가 늘 수 있으므로 필요한 기간만 지정하세요. 와일드카드 테이블과 접미사 필터는 Google Cloud 공식 문서를 참고하세요.
3단계: 결과와 누락 값을 점검합니다
쿼리를 실행해 결과의 session_count를 확인합니다. user_pseudo_id 또는 ga_session_id가 없는 행은 세션 키를 만들 수 없어 집계에서 제외됩니다. 누락 규모를 파악하려면 별도 진단 쿼리로 해당 필드가 비어 있는 이벤트 행을 확인하세요. 세션 ID 추출 결과가 예상보다 적다면 이벤트 매개변수의 키 이름과 데이터세트 테이블 경로부터 점검합니다.
세션 시작일 기준으로 날짜별 집계하기

이벤트 날짜와 세션 날짜의 차이
앞의 쿼리는 조회 기간 중 이벤트가 발생한 세션을 전체 기간에 대해 한 번씩 셉니다. 반면 날짜별 세션 추이를 보려면 날짜 기준을 정해야 합니다. 자정을 지나 이어진 세션은 여러 날짜의 이벤트에 나타날 수 있어, 이벤트 날짜로 그룹화하면 각 날짜에 한 번씩 집계될 수 있습니다.
session_start 이벤트로 시작 날짜를 지정하기
세션이 시작된 날짜별 수가 필요하면 session_start 이벤트를 기준으로 집계할 수 있습니다. event_date는 GA4 보고 시간대 기준 날짜입니다. 다음 SQL은 조회 기간 안에서 시작한 세션을 날짜별로 계산합니다. Google은 세션 시작 시 session_start 이벤트를 자동으로 수집하고 세션 ID를 생성한다고 안내합니다. 다만 구현 방식이나 필터링에 따라 해당 이벤트가 내보내기에 없을 수 있으므로, 결과가 예상과 다르면 데이터도 확인하세요.
WITH session_starts AS (
SELECT
event_date,
user_pseudo_id,
(SELECT value.int_value
FROM UNNEST(event_params)
WHERE key = 'ga_session_id'
LIMIT 1) AS ga_session_id
FROM `프로젝트ID.데이터세트.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20261001' AND '20261007'
AND event_name = 'session_start'
)
SELECT
event_date,
COUNT(DISTINCT STRUCT(user_pseudo_id, ga_session_id)) AS session_count
FROM session_starts
WHERE user_pseudo_id IS NOT NULL
AND ga_session_id IS NOT NULL
GROUP BY event_date
ORDER BY event_date;
두 쿼리는 서로 다른 질문에 답합니다. 전체 기간 쿼리는 기간 중 활동이 확인된 세션을 세고, session_start 쿼리는 기간 안에 시작한 세션을 날짜별로 나눕니다. 보고서와 비교할 때는 날짜 기준과 세션 범위를 먼저 맞추세요.
결과가 GA4 보고서와 다를 때 점검할 항목

- 날짜와 시간대: BigQuery의 테이블 접미사와
event_date는 GA4 보고 시간대 기준과 대조해야 합니다. GA4 속성의 시간대와 선택한 기간이 같은지 확인합니다. - 세션 범위: 기간 중 이벤트가 있는 세션을 셌는지, 기간 안에 시작한 세션만 셌는지 확인합니다.
- 식별자 누락: 사용자 또는 세션 ID가 없는 이벤트는 위 SQL에서 집계되지 않습니다.
- 집계 방식: GA4 보고서는 세션 수에 HLL++ 근사 집계를 사용하고 BigQuery의 고유 조합 쿼리는 정확한 개수를 계산하므로 결과가 조금 다를 수 있습니다. 자세한 배경은 Google 애널리틱스의 세션 수 차이 안내를 참고하세요.
- 기준 대조: 날짜, 필터, 세션 정의를 하나씩 비교하려면 GA4·BigQuery 불일치 원인 점검 절차를 참고하세요.
날짜별 세션 수가 필요하다면 날짜 기준을 먼저 정하세요. 이벤트 발생일 집계와 세션 시작일 집계는 자정을 넘는 세션에서 결과가 달라질 수 있습니다.
비용과 집계 정확도를 함께 관리하는 법

BigQuery에서 필요한 열만 읽도록 쿼리를 구성하고 _TABLE_SUFFIX 범위를 좁히면 불필요한 테이블 조회와 데이터 처리를 줄이는 데 도움이 됩니다. 실제 처리 바이트는 쿼리 실행 전에 확인하세요. 테이블의 이벤트 매개변수 구조나 내보내기 설정이 다르면 결과도 달라질 수 있으므로 스키마를 기준으로 SQL을 검토해야 합니다.
이 쿼리는 정확한 고유 조합 집계를 사용합니다. 대규모 데이터에서 근사 세션 수가 허용되는 분석이라면 Google이 안내하는 HLL++ 방식도 선택지입니다. 다만 정확한 수치 비교가 목적이라면 위의 고유 조합 쿼리로 계산한 결과와 비교 기준을 맞추세요. Google은 세션 근사 집계 방식과 정밀도 설정을 고유 개수 근사값 안내에서 설명합니다.
자주 묻는 질문
Q. ga_session_id만 COUNT하면 안 되나요?
사용자별 세션 시작 시각이 같을 수 있으므로 단독 집계는 서로 다른 세션을 합칠 수 있습니다. user_pseudo_id와 ga_session_id를 하나의 조합으로 세세요.
Q. event_name을 session_start로 제한하는 게 항상 맞나요?
질문에 따라 다릅니다. 기간 중 이벤트가 있는 고유 세션을 세려면 전체 이벤트에서 고유 조합을 계산하고, 기간 안에 시작한 세션만 날짜별로 보고 싶다면 session_start 이벤트를 기준으로 삼으세요.
Q. 날짜별 결과를 더하면 전체 쿼리 결과와 다를 수 있나요?
네. 이벤트 날짜별로 세면 자정을 넘어 활동한 세션이 여러 날짜에 포함될 수 있습니다. 세션 시작일 기준으로 나눈 집계인지 확인한 뒤 전체 기간 수와 비교하세요.
Q. ga_session_id가 없는 이벤트는 어떻게 처리하나요?
해당 행에는 세션 키를 만들 수 없으므로 위 SQL은 제외합니다. 누락이 많다면 내보내기 테이블의 스키마와 event_params에 실제로 ga_session_id가 들어오는지 점검하세요.
Q. GA4 화면의 세션 수와 BigQuery 결과가 다르면 SQL 오류인가요?
꼭 그렇지는 않습니다. GA4 보고서는 HLL++ 근사 집계, BigQuery 쿼리는 정확한 고유 개수 집계를 사용할 수 있고 날짜 범위와 시간대, 세션 귀속 기준도 결과에 영향을 줍니다. 두 결과의 기준을 맞춘 뒤 필터와 식별자 누락 여부를 비교하세요.
