크로스 소스 설정 복잡한 시나리오 및 SQL 예시
1. 크로스 소스 이벤트 테이블
1.1 이벤트 시간
자주 쓰이는 시간 정보 기록 형식과 처리 방법은 다음과 같습니다:
| 가정 필드 이름 | 가정 값 예시 | 데이터 타입 | 비고 |
|---|---|---|---|
| event_time | 2025-10-15 08:12:34 | 시간 | 내용&타입 모두 올바름 |
페이지 설정
- 값 가져오기 방식= 열 값 읽기
- 이벤트 시간 열= event_time
| 가정 필드 이름 | 가정 값 예시 | 데이터 타입 | 비고 |
|---|---|---|---|
| time_str_a | '2025-10-15 08:12:34' | 텍스트 | 내용 올바름 타입 변환 |
페이지 설정
- 값 가져오기 방식= 커스텀 SQL
try_cast( time_str_a as timestamp )
| 가정 필드 이름 | 가정 값 예시 | 데이터 타입 | 비고 |
|---|---|---|---|
time_str_b | '15/Oct/2025 13:56:36.864' | 텍스트 | 특수 형식 일월년_시분초_밀리초 파싱 함수 사용 |
페이지 설정
- 값 가져오기 방식= 커스텀 SQL
try( date_parse( time_str_b, '%d/%b/%Y %H:%i:%s.%f' ) )
더 많은 형식 문자는 다음을 참고하십시오: SQL 매뉴얼
| 가정 필드 이름 | 가정 값 예시 | 데이터 타입 | 비고 |
|---|---|---|---|
| time_str_c | '25/10/15 08:12:34' | 텍스트 | 특수 형식 연월일_시분초 파싱 함수 사용 |
페이지 설정
- 값 가져오기 방식= 커스텀 SQL
try( date_parse( time_str_c, '%y/%m/%d %H:%i:%s' ) )
더 많은 형식 문자는 다음을 참고하십시오: SQL 매뉴얼
| 가정 필드 이름 | 가정 값 예시 | 데이터 타입 | 비고 |
|---|---|---|---|
| ts_10 | 1760506518 | 숫자 | 10자리 숫자 타임스탬프 파싱 함수 사용 *시간대는 쿼리 엔진이 설치된 시간대입니다 |
페이지 설정
- 값 가져오기 방식= 커스텀 SQL
try( from_unixtime( ts_10 ) )
| 가정 필드 이름 | 가정 값 예시 | 데이터 타입 | 비고 |
|---|---|---|---|
| ts_10 | 1760506518 | 숫자 | 10자리 숫자 타임스탬프 파싱 함수 사용 *시간대는 쿼리 엔진이 설치된 시간대입니다 |
| tz | Asia/Kolkata | 텍스트 | *데이터 전송 시점의 시간대이며, 현지 시간으로 복원해야 합니다 |
페이지 설정
- 값 가져오기 방식= 커스텀 SQL
try( from_unixtime( ts_10, tz ) )
| 가정 필드 이름 | 가정 값 예시 | 데이터 타입 | 비고 |
|---|---|---|---|
| ts_13 | 1760506518123 | 숫자 | 13자리 숫자 타임스탬프 *시간대는 쿼리 엔진이 설치된 시간대입니다 |
페이지 설정
- 값 가져오기 방식= 커스텀 SQL
try( from_unixtime( ts_13 / 1000.000 ) )
1.2 이벤트 시간대
자주 쓰이는 시간대 기록 방법은 다음과 같습니다:
| 가정 필드 이름 | 가정 값 예시 | 데이터 타입 | 비고 |
|---|---|---|---|
| TIMEZONE | 8 | 숫자 | 내용&타입 모두 올바름 |
페이지 설정
- 값 가져오기 방식= 열 값 읽기
- 이벤트 시간대 열= TIMEZONE
| 가정 필드 이름 | 가정 값 예시 | 데이터 타입 | 비고 |
|---|---|---|---|
| TIMEZONE_A | '8' | 텍스트 | 내용 올바름 타입 변환 사용 |
페이지 설정
- 값 가져오기 방식= 커스텀 SQL
try_cast( TIMEZONE_A as double )
| 가정 필드 이름 | 가정 값 예시 | 데이터 타입 | 비고 |
|---|---|---|---|
| TIMEZONE_B | 'Asia/Shanghai' | 텍스트 | 지리 정보 시간대 텍스트 타입 시차 계산으로 변환 |
페이지 설정
- 값 가져오기 방식= 커스텀 SQL
try(
date_diff( /*두 시각의 차이*/
'minute', /*분 단위로 계산*/
cast( '2018-01-01 00:00:00'||"TIMEZONE_B" as timestamp with time zone ),
timestamp'2018-01-01 00:00:00+00:00'
)
/60.0 /*시간 단위로 변환, 소수점 포함*/
)
| 가정 필드 이름 | 가정 값 예시 | 데이터 타입 | 비고 |
|---|---|---|---|
| TIMEZONE_C | '08:00' | 텍스트 | 시각 정보 시간대 텍스트 타입 시차 계산으로 변환 |
- 값 가져오기 방식= 커스텀 SQL
try(
date_diff( /*두 시각의 차이*/
'minute', /*분 단위로 계산*/
cast( '2018-01-01 00:00:00'||"TIMEZONE_C" as timestamp with time zone ),
timestamp'2018-01-01 00:00:00+00:00'
)
/60.0 /*시간 단위로 변환, 소수점 포함*/
)
1.3 파티션 방식과 푸시다운 로직
1.3.1 기본 설명
분석 모델로 조회할 때 프런트엔드 페이지에서 사용자가 조회할 날짜 범위를 선택하면, 시스템은 그 범위에 따라 데이터를 필터링합니다
일반적으로 기반 테이블에는 날짜별로 기록된 파티션 필드가 있으며, 이 필드로 불필요한 데이터를 먼저 걸러 내면 조회 성능을 높일 수 있습니다
| part_date | data | ... |
|---|---|---|
| 2025-10-01 | ... | ... |
| 2025-10-02 | ... | ... |
| 2025-10-03 | ... | ... |
| 2025-10-04 | ... | ... |
| 2025-10-05 | ... | ... |
예시: 기반 테이블에 part_date 파티션 열이 있음
사용자가 페이지에서 날짜 범위를 선택
| part_date | data | ... |
|---|---|---|
| 2025-10-01 | ... | ... |
| 2025-10-02 | ... | ... |
| 2025-10-03 | ... | ... |
| 2025-10-04 | ... | ... |
| 2025-10-05 | ... | ... |
시스템은 필요한 데이터만 조회
프런트엔드가 백엔드로 보내는 파티션 필터 로직
part_date between
date'2025-10-01' /*날짜 시작*/
and
date'2025-10-03' /*날짜 끝*/
그중 변수 부분은 다음과 같습니다:
part_date between
${start_date} /*날짜 시작*/
and
${end_date} /*날짜 끝*/
/* 변수의 데이터 타입은 date입니다 */
/* 이 SQL이 바로 푸시다운 로직이며, 조회 시 시스템이 WHERE 절에 이어 붙입니다 */
시간대 오프셋 문제가 있으므로 파티션 푸시다운 로직 필터링은 첫 번째 단계의 필터링 로직으로만 사용됩니다
이후 실제 이벤트 시간을 기준으로 데이터를 한 번 더 필터링합니다
1.3.2 파티션 방식 예시
| part_date | data | ... |
|---|---|---|
| '2025-10-01' | ... | ... |
| '2025-10-02' | ... | ... |
| '2025-10-03' | ... | ... |
| '2025-10-04' | ... | ... |
| '2025-10-05' | ... | ... |
- 내용은 하이픈으로 구분된 연월일이고, 타입은 텍스트입니다
- AE 시스템의 구조와 같습니다
- 날짜 정보 열과 형식만 선택하면 됩니다
| part_date | data | ... |
|---|---|---|
| '2025/10/01' | ... | ... |
| '2025/10/02' | ... | ... |
| '2025/10/03' | ... | ... |
| '2025/10/04' | ... | ... |
| '2025/10/05' | ... | ... |
- 내용은 슬래시로 구분된 연월일이고, 타입은 텍스트입니다
- 날짜 정보 열과 형식만 선택하면 됩니다
| part_date | data | ... |
|---|---|---|
| 20251001 | ... | ... |
| 20251002 | ... | ... |
| 20251003 | ... | ... |
| 20251004 | ... | ... |
| 20251005 | ... | ... |
- 내용은 연월일 숫자이고, 타입은 숫자입니다
타입이 텍스트인 경우에도 적용됩니다
- 날짜 정보 열과 형식만 선택하면 됩니다
| part_date | data | ... |
|---|---|---|
| 1759248000 | ... | ... |
| 1759334400 | ... | ... |
| 1759420800 | ... | ... |
| 1759507200 | ... | ... |
| 1759593600 | ... | ... |
- 내용은 매일 0시의 10자리 숫자 타임스탬프이고, 타입은 숫자입니다
텍스트 타입이면 먼저 숫자로 변환해야 합니다
13자리 숫자 타임스탬프라면 변수를 타임스탬프로 변환한 후 1000을 곱해야 합니다
- 커스텀 푸시다운 로직을 선택하고 SQL을 설정합니다
part_date between
try( to_unixtime( ${start_date} ) )
and
try( to_unixtime( ${end_date} ) )
| year_p | month_p | day_p | data | ... |
|---|---|---|---|---|
| 2025 | 10 | 1 | ... | ... |
| 2025 | 10 | 2 | ... | ... |
| 2025 | 10 | 3 | ... | ... |
| 2025 | 10 | 4 | ... | ... |
| 2025 | 10 | 5 | ... | ... |
- 파티션 열 3개에 각각 연/월/일 정보를 기록하며, 타입은 숫자입니다
- 커스텀 푸시다운 로직을 선택하고 SQL을 설정합니다
array_position( transform(sequence( ${start_date} , ${end_date} ), x -> year(x) ) , "year_p" ) > 0
and array_position( transform(sequence( ${start_date} , ${end_date} ), x -> month(x) ) , "month_p" ) > 0
and array_position( transform(sequence( ${start_date} , ${end_date} ), x -> day(x) ) , "day_p" ) > 0
/*월이나 연도가 바뀌는 경우를 고려해야 합니다*/
2. 리소스 목록 값 가져오기 방식
원본 열 이름이
prop1,prop2,prop3...이라고 가정합니다스크린샷에서 긴 SQL은 일부만 표시될 수 있으므로, 전체 SQL은 각 소절의 코드 블록을 기준으로 합니다.
2.1 타입 변환
| 골드 획득(원본 데이터) | 골드 획득(변환 후) |
|---|---|
| '1024' | 1024 |
- 원본 데이터의 "골드 획득" 열은 텍스트 타입을 사용합니다
- 숫자 연산을 할 수 없습니다
- 숫자 타입으로 변환해야 합니다
- 값 가져오기 방식에서 SQL을 설정합니다
try_cast( prop1 as double )
2.2 텍스트 연결
| 서버 ID(원본 데이터) | 유저 ID(원본 데이터) | 유저 고유 ID(변환 후) |
|---|---|---|
| SVAP | U01 | SVAPU01 |
- 원본 데이터의 유저 ID는 서버별로 중복될 수 있습니다
- 서버 ID와 결합해야 유저의 고유 ID를 확정할 수 있습니다
- 두 값을 연결해야 합니다
- 값 가져오기 방식에서 SQL을 설정합니다
try( concat( "prop1", "prop2" ) )
2.3 텍스트 분할
| 광고 집행 정보(원본 데이터) | 지역(변환 후) | 그룹(변환 후) | 멤버(변환 후) |
|---|---|---|---|
| 화둥,1그룹,홍길동 | 화둥 | 1그룹 | 홍길동 |
- 원본 데이터의 텍스트에 여러 정보가 포함되어 있습니다
- 사용할 때 분할하여 각각 사용하려고 합니다
- 값 가져오기 방식에서 SQL을 설정합니다
try( split_part( "prop1" , ',', 1 ) )
/*쉼표로 분할하여 1번째 부분을 가져옵니다. 작은따옴표와 큰따옴표에 주의하십시오*/
try( split_part( "prop1" , ',', 2 ) )
/*쉼표로 분할하여 2번째 부분을 가져옵니다. 작은따옴표와 큰따옴표에 주의하십시오*/
try( split_part( "prop1" , ',', 3 ) )
/*쉼표로 분할하여 3번째 부분을 가져옵니다. 작은따옴표와 큰따옴표에 주의하십시오*/
2.4 객체에서 하위 속성 추출
| 아이템 정보(원본 데이터) | 아이템 가격(변환 후) |
|---|---|
| {"item_id":"apple","item_price":88} | 88 |
- 원본 데이터의 객체에 아이템 id와 아이템 가격이 포함되어 있습니다
- 사용할 때 그중 아이템 가격을 추출하려고 합니다
- 값 가져오기 방식에서 SQL을 설정합니다
try( "prop1"."item_price" )
2.5 텍스트를 객체로 변환
| 아이템 정보 텍스트(원본 데이터) | 아이템 정보(변환 후) |
|---|---|
| '{"item_id":"apple","item_price":88}' | {"item_id":"apple","item_price":88} |
- 원본 데이터는 JSON 텍스트로 아이템 정보를 기록합니다
- 사용할 때 객체 데이터 타입으로 변환하려고 합니다
- 값 가져오기 방식에서 SQL을 설정합니다
try_cast( json_parse( "prop1" ) as row( item_id varchar, item_price double ) )

