SnowConvert: Teradata

숫자 데이터 연산

계산 전체 자릿수

Teradata와 Snowflake는 계산을 다르게 처리합니다.

  • Teradata는 데이터 타입에 따라 각 계산 단계 후에 숫자를 반올림합니다.

    • 소수점 유형의 경우 더 큰 전체 자릿수를 유지합니다

    • NUMBER 유형의 경우, 완전한 전체 자릿수를 유지합니다

  • Snowflake는 NUMBER 데이터 타입을 사용하여 모든 숫자를 저장하므로 전체 계산 시간 동안 완전한 전체 자릿수를 유지합니다. 특히 소수점, 정수 또는 부동 소수점 유형으로 작업할 때 Teradata와 다른 결과가 나올 수 있습니다.

이러한 동작 차이는 일반적으로 개발자가 변경하려는 의도가 아니므로 코드 변환 중에 조정되지 않습니다.

Teradata: SELECT (1.00/28) * 15.00 /* 반환 0.60 */

Snowflake는 나누기 결과(1.00/28) * 15.00을 소수점 이하 두 자리로 반올림:SELECT (1.00/28) * 15.00 = 0.535710 = 0.54

정수-정수 나눗셈

두 정수 값을 나눌 때 Teradata는 자르기(바닥)를 수행하는 반면, Snowflake는 반올림을 수행합니다. 마이그레이션 중 일관된 동작을 유지하기 위해 자동화된 코드 변환은 이러한 경우 TRUNC 문을 자동으로 추가합니다.

Teradata: SELECT (5/3) = 1 /정수를 나누면 반내림되므로 1을 반환합니다/

Snowflake: 5를 3으로 나누면 결과는 1.6666666이며 반올림하면 2가 됩니다

잘린 나눗셈의 Snowflake: SELECT TRUNC (5/3)는 1을 반환합니다

뱅커 반올림

Teradata는 ROUNDHALFWAYMAGUP 매개 변수를 통해 Banker의 반올림을 제공하는 반면, Snowflake는 표준 반올림 방법만 사용합니다.

SQL

Teradata

Snowflake

CAST( 1.05 AS DECIMAL(9,1))

1.0

1.1

CAST( 1.15 AS DECIMAL(9,1))

1.2

1.2

CAST( 1.25 AS DECIMAL(9,1))

1.2

1.3

CAST( 1.35 AS DECIMAL(9,1))

1.4

1.4

CAST( 1.45 AS DECIMAL(9,1))

1.4

1.5

CAST( 1.55 AS DECIMAL(9,1))

1.6

1.6

CAST( 1.65 AS DECIMAL(9,1))

1.6

1.7

CAST( 1.75 AS DECIMAL(9,1))

1.8

1.8

CAST( 1.85 AS DECIMAL(9,1))

1.8

1.9

CAST( 1.95 AS DECIMAL(9,1))

2.0

2.0

소수점에서 정수로 변환

Teradata와 Snowflake는 소수점 값을 다르게 처리합니다. Teradata는 소수점 값을 잘라내는 반면, Snowflake는 가장 가까운 정수로 반올림합니다. Teradata의 동작과 일관성을 유지하기 위해 변환 프로세스에서는 TRUNC 문을 자동으로 추가합니다.

SQL

Teradata

Snowflake

CAST( 1.0 AS INTEGER)

1

1

CAST( 1.1 AS INTEGER)

1

1

CAST( 1.2 AS INTEGER)

1

1

CAST( 1.3 AS INTEGER)

1

1

CAST( 1.4 AS INTEGER)

1

1

CAST( 1.5 AS INTEGER)

1

2

CAST( 1.6 AS INTEGER)

1

2

CAST( 1.7 AS INTEGER)

1

2

CAST( 1.8 AS INTEGER)

1

2

CAST( 1.9 AS INTEGER)

1

2

전체 자릿수/스케일이 없는 숫자

스케일 또는 전체 자릿수를 지정하지 않고 Teradata NUMBER 열을 정의하는 경우, 총 전체 자릿수가 38자리 이내로 유지되는 한 다양한 스케일(0~38)의 소수점 값을 저장할 수 있습니다. 그러나 Snowflake에서는 NUMBER 열에 대한 스케일 및 전체 자릿수 값을 수정해야 합니다. 다음은 이 유연한 형식의 Teradata 테이블에서 숫자를 정의하는 방법의 예입니다.

CREATE MULTISET TABLE DATABASEXYZ.TABLE_NUMS
     (NUM_COL1 NUMBER(*),
      NUM_COL2 NUMBER,
      NUM_COL3 NUMBER(38,*));
Copy

다음 테이블에는 Snowflake의 열 크기 제한을 초과하는 값의 두 가지 예가 나와 있습니다. 이러한 값은 이전에 표시된 모든 Teradata 열에 나타날 수 있습니다.

값 1: 123,345,678,901,234,567,891,012.0123456789

값 2: 123.12345678901234567890

이러한 숫자 값에는 NUMBER(42, 20) 데이터 타입이 필요하며, 이는 Snowflake의 최대 전체 자릿수 제한인 38을 초과합니다. Snowflake는 현재 유연한 전체 자릿수 및 스케일 기능을 구현하기 위해 노력하고 있습니다.

SQL DML 문의 INSERT 에서 잘라내기

Teradata는 삽입 중에 정의된 필드 길이를 초과하는 문자열 값을 자동으로 잘라냅니다. SnowConvert 는 변환 중에 동일한 필드 길이를 유지하지만(예: VARCHAR(20)은 VARCHAR(20)으로 유지), Snowflake는 크기가 큰 문자열을 자동으로 잘라내지 않습니다. 데이터 수집 프로세스가 자동 잘림에 종속성이 있는 경우 LEFT() 함수를 추가하여 수동으로 수정해야 합니다. SnowConvert 는 전체 코드베이스에 영향을 미칠 수 있으므로 의도적으로 자동으로 잘림을 추가하지 않습니다.

부동 소수점 기본 문제 예제:

/* <sc-table> TABLE DUMMY.EXAMPLE </sc-table> */
/**** WARNING: SET TABLE FUNCTIONALITY NOT SUPPORTED ****/
CREATE TABLE DUMMY.PUBLIC.EXAMPLE (
LOGTYPE INTEGER,
OPERSEQ INTEGER DEFAULT 0,
RUNTIME FLOAT /**** ERROR: DEFAULT CURRENT_TIME NOT VALID FOR DATA TYPE ****/
);
Copy

부동 소수점 데이터 집계

부동 소수점 숫자는 소수점 값의 대략적인 표현입니다. 이러한 근사치로 인해, 실수 데이터 타입으로 계산 및 집계를 수행할 때 데이터베이스 시스템마다 약간씩 다른 결과가 나올 수 있습니다. 이러한 차이는 각 데이터베이스 시스템이 부동소수점 연산과 반올림을 고유한 방식으로 처리하기 때문에 발생합니다.

기타 고려 사항

조인 제거

Snowflake는 최종 결과에 영향을 미치는지 여부에 관계없이 지정된 모든 조인을 포함하여 SQL 쿼리를 작성된 대로 정확하게 실행합니다. Snowflake와 달리 Teradata는 테이블 구조에 정의된 기본 키 및 외래 키 관계를 사용하여 불필요한 조인을 자동으로 제거할 수 있습니다. Teradata의 이 기능은 주로 잘못 작성된 쿼리를 방지하는 데 도움이 되며, 일반적으로 이 기능을 사용하도록 특별히 코드가 작성된 경우에만 문제가 됩니다. 기존 코드가 Teradata의 조인 제거 기능을 활용하도록 설계된 경우, 자동화된 코드 변환 도구로는 이 제한을 해결할 수 없습니다. 이러한 경우 솔루션의 일부를 다시 설계해야 할 수도 있습니다.

max() 및 order by로 윈도우 함수 사용하기

Teradata 동작 및 기본값:

기본값: ORDER BY 절이 있지만, ROWS 또는 ROWS BETWEEN 절이 지정되지 않은 경우, Teradata SQL 윈도우 집계 함수는 자동으로 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING 를 사용합니다.

Snowflake 동작 및 기본값:

기본값: ROWS 또는 ROWS BETWEEN 을 지정하지 않고 ORDER BY 절이 있는 윈도우 집계 함수를 사용하면, Snowflake는 자동으로 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 를 윈도우 프레임으로 적용합니다.

예:

다음은 TEST_WIN 이라는 이름의 테이블로, 여러 부서의 직원 급여 데이터를 보여줍니다.

DEPT_NMDEPT_NOEMP_NOSALARY
SALES10115000
SALES10126000
HR20211000
HR20222000
PS30317000
PS30329000

다음 코드를 Teradata에서 실행하면 부서별로 그룹화된 모든 직원 중 가장 높은 급여를 계산합니다.

SELECT DEPT_NM, SALARY ,DEPT_NO,
MAX(SALARY) OVER ( ORDER BY DEPT_NO  ) AS MAX_DEPT_SALARY
FROM TEST_WIN;
Copy
DEPT_NMSALARYDEPT_NOMAX_DEPT_SALARY
SALES6000109000
SALES5000109000
HR2000209000
HR1000209000
PS7000309000
PS9000309000

변환된 코드를 Snowflake-SnowConvert 를 사용하여 실행하면 다른 결과(강조 표시된 값)를 확인할 수 있습니다. 이러한 차이는 예상되는 것이며 Snowflake의 기본 설정과 일치합니다.

SELECT DEPT_NM, SALARY ,DEPT_NO,
MAX(SALARY) OVER ( ORDER BY DEPT_NO  ) AS MAX_DEPT_SALARY
FROM TEST_WIN;
Copy
DEPT_NMSALARYDEPT_NOMAX_DEPT_SALARY
SALES5000106000
SALES6000106000
HR1000206000
HR2000206000
PS7000309000
PS9000309000

Teradata에서와 동일한 결과를 얻으려면 아래 코드에 표시된 대로 ROWS/RANGE 값을 지정해야 합니다.

SELECT DEPT_NM, SALARY ,DEPT_NO,
MAX(SALARY) OVER ( ORDER BY DEPT_NO RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS MAX_DEPT_SALARY
FROM TEST WIN;
Copy
DEPT_NMSALARYDEPT_NOMAX_DEPT_SALARY
SALES5000109000
SALES6000109000
HR1000209000
HR2000209000
PS7000309000
PS9000309000

RANGE/ROWS 절은 행 순서를 지정하는 방법을 명시적으로 정의합니다. ORDER BY 절을 완전히 제거해도 비슷한 결과를 얻을 수 있습니다.

참조

Snowflake: https://docs.snowflake.com/en/sql-reference/functions-analytic.html Teradata: https://docs.teradata.com/r/756LNiPSFdY~4JcCCcR5Cw/dIV_fAtkK3UeUIQ5_uucQw