SnowConvert AI - Teradata - DML

이 섹션에서는 데이터 조작 언어 요소의 변환 참조에 대한 설명서를 확인할 수 있습니다.

Delete 문

Delete 문 참조

Teradata는 FROM 절에서 둘 이상의 테이블 호출을 지원하지만, Snowflake는 지원하지 않습니다. 따라서 조건에 관련된 추가 테이블을 참조하려면 USING 절을 사용해야 합니다.

Teradata

Delete

DEL FROM MY_TABLE ALL;
DEL FROM MY_TABLE_2 WHERE COL1 > 50;
DELETE T1 FROM TABLE1 T1, TABLE2 T2 WHERE T1.ID = T2.ID;
DELETE FROM TABLE1 T1, TABLE2 T2 WHERE T1.ID = T2.ID;
DELETE T1 FROM TABLE2 T2, TABLE1 T1 WHERE T1.ID = T2.ID;
DELETE FROM TABLE1 WHERE TABLE1.COLUMN1 = TABLE2.COLUMN2
Copy

Snowflake

Delete

DELETE FROM
MY_TABLE;

DELETE FROM
MY_TABLE_2
WHERE
COL1 > 50;

DELETE FROM
TABLE1 T1
USING TABLE2 T2
WHERE
T1.ID = T2.ID;

DELETE FROM
TABLE1 T1
USING TABLE2 T2
WHERE
T1.ID = T2.ID;

DELETE FROM
TABLE1 T1
USING TABLE2 T2
WHERE
T1.ID = T2.ID;

DELETE FROM
TABLE1
WHERE
TABLE1.COLUMN1 = TABLE2.COLUMN2;
Copy

Known Issues

1. DEL abbreviation unsupported

이 약어는 Snowflake에서 지원되지 않지만, DELETE 로 변경하면 올바르게 변환됩니다.

세트 연산자

SQL 세트 연산자는 각 쿼리의 결과를 단일 결과 세트로 결합하는 여러 쿼리의 결과 세트를 조작합니다.

참고

출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.

Teradata와 Snowflake의 Set 연산자는 EXCEPT, INTERSECT, UNION 에서 ALL 절을 제외하고는 구문과 지원 시나리오가 동일하며, INTERSECTALL 에서는 지원하지 않으므로 변환 후 ALL 의 일부가 주석 처리된 코드가 됩니다.

Teradata

Intersect

 SELECT LastName, FirstName FROM employees
INTERSECT
SELECT FirstName, LastName FROM contractors;

SELECT LastName, FirstName FROM employees
INTERSECT ALL
SELECT FirstName, LastName FROM contractors;
Copy

Snowflake

Intersect

 SELECT
LastName,
FirstName FROM
employees
INTERSECT
SELECT
FirstName,
LastName FROM
contractors;

SELECT
LastName,
FirstName FROM
employees
INTERSECT
        !!!RESOLVE EWI!!! /*** SSC-EWI-0040 - THE 'INTERSECT ALL QUANTIFIER' CLAUSE IS NOT SUPPORTED IN SNOWFLAKE ***/!!! ALL
SELECT
FirstName,
LastName FROM
contractors;
Copy

Known Issues

1. INTERSECT ALL unsupported

INTERSECTALL 은 Snowflake에서 지원되지 않으며 ALL 부분에 설명이 추가됩니다.

관련 EWIs

  1. SSC-EWI-0040: 문이 지원되지 않습니다.

Update 문

설명

테이블의 기존 행에서 열 값을 수정합니다. (Teradata SQL 언어 참조 UPDATE)

샘플 소스 패턴

기본 사례

Teradata

Update

 UPDATE CRASHDUMPS.TABLE1 i
 SET COLUMN4 = CRASHDUMPS.TABLE2.COLUMN3
 WHERE i.COLUMN1 = CRASHDUMPS.TABLE2.COLUMN1
 AND i.COLUMN3 = 'L';
Copy

Snowflake

Update

UPDATE CRASHDUMPS.TABLE1 AS i
 SET
  i.COLUMN4 = CRASHDUMPS.TABLE2.COLUMN3
 FROM
  CRASHDUMPS.TABLE2
  WHERE i.COLUMN1 = CRASHDUMPS.TABLE2.COLUMN1
  AND UPPER(RTRIM( i.COLUMN3)) = UPPER(RTRIM('L'));
Copy

순방향 별칭이 있는 UPDATE

Teradata는 별칭을 선언하기 전에 참조하는 기능을 지원하지만, Snowflake는 지원하지 않습니다. 이 시나리오의 변환은 참조된 테이블을 가져와서 참조하는 테이블 이름의 별칭을 변경하는 것입니다.

Teradata

Update

 UPDATE i
 FROM CRASHDUMPS.TABLE2, CRASHDUMPS.TABLE1 i
 SET COLUMN4 = CRASHDUMPS.TABLE2.COLUMN3
 WHERE i.COLUMN1 = CRASHDUMPS.TABLE2.COLUMN1
 AND i.COLUMN3 = 'L';
Copy

Snowflake

Update

UPDATE CRASHDUMPS.TABLE1 AS i
  SET
  i.COLUMN4 = CRASHDUMPS.TABLE2.COLUMN3
  FROM
  CRASHDUMPS.TABLE2
  WHERE i.COLUMN1 = CRASHDUMPS.TABLE2.COLUMN1
  AND UPPER(RTRIM( i.COLUMN3)) = UPPER(RTRIM('L'));
Copy

FROM 절에 대상 테이블이 있는 UPDATE

Teradata는 FROM 절에 정의된 대상 테이블을 지원합니다. 이는 중복 별칭과 모호한 열 참조 오류를 방지하기 위해 Snowflake에서 제거되었습니다.

Teradata

Update

UPDATE some_table
FROM some_table
SET Code = Code + 100
WHERE Name = 'A';
Copy

Snowflake

Update

UPDATE some_table
  SET Code = Code + 100
  WHERE
  UPPER(RTRIM( Name)) = UPPER(RTRIM('A'));
Copy

관련 EWIs

관련 EWIs 없음.

With Modifier

WITH 한정자를 사용하여 여러 명명된 쿼리 목록을 포함하는 Select 문(공통 테이블 식(CTEs)을 선택합니다.

Snowflake는 여러 개의 CTEs (공통 테이블 식)이 있는 SELECT 문에서 Teradata의 WITH 수정자를 지원합니다. Teradata는 CTE 정의가 선언되기 전에 참조되는지 여부에 관계없이 모든 순서를 지원하지만, Snowflake는 CTE 가 다른 CTE 를 호출하는 경우 반드시 그 전에 정의할 것을 요구합니다. 그런 다음 WITH 내에서 변환된 CTEs 시퀀스는 참조되지 않은 CTEs, 다음 CTE 를 호출하는 CTE 로 순서가 재지정됩니다.

WITH 호출 시퀀스에서 주기가 감지된 경우 SSC-EWI-TD0077의 예에 자세히 설명된 대로 시퀀스가 변경되지 않고 원본 그대로 유지됩니다.

아래 예에서 두 개의 CTEs는 n1 및 n2로 명명되며, n1은 n2를 나타냅니다. 그런 다음 n2를 Snowflake에서 해당 변환 코드로 먼저 정의해야 합니다.

참고

출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.

Teradata

With Modifier

 WITH recursive n1(c1) as (select c1, c3 from t2, n1),
     n2(c2) as (select c2 from tablex)
     SELECT * FROM t1;
Copy

Snowflake

With Modifier

 WITH RECURSIVE n1(c1) AS
(
     SELECT
          c1,
          c3 from
          t2, n1
),
n2(c2) AS
(
     SELECT
          c2 from
          tablex
)
SELECT
     * FROM
     t1;
Copy

Known Issues

1. Impossible to reorder when cycles were found

CTEs 참조가 분석되고 CTEs 호출 사이에 주기가 있는 경우 CTEs 는 주문되지 않습니다.

관련 EWIs

관련 EWIs 없음.

Insert 문

테이블에 새 행을 추가하는 SQL 문입니다.

참고

출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.

Insert 문 참조

Teradata에는 각 테이블 열의 값을 인라인으로 할당하는 대체 INSERT 구문이 있습니다. 이 대체 구조를 사용하려면 Snowflake에서 지원되는 특수 변환이 필요합니다. 값의 인라인 할당은 분리되어 Snowflake INSERT INTO 문의 VALUES(...) 부분 내에 배치됩니다.

Teradata

삽입

 INSERT INTO appDB.logTable (
    process_name = 'S2F_BOOKS_LOAD_NEW'
    , session_id = 105678989 
    , message_txt = '' 
    , message_ts = '2019-07-23 00:00:00'
    , Insert_dt = CAST((CURRENT_TIMESTAMP(0)) AS DATE FORMAT 'YYYY-MM-DD'));
Copy

Snowflake

삽입

 INSERT INTO appDB.logTable (
process_name, session_id, message_txt, message_ts, Insert_dt)
VALUES ('S2F_BOOKS_LOAD_NEW', 105678989, '', '2019-07-23 00:00:00', TO_DATE((CURRENT_TIMESTAMP(0))));
Copy

알려진 문제

문제가 발견되지 않았습니다.

관련 EWIs

관련 EWIs 없음.

LOGGING ERRORS

참고

출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.

참고

관련 없는 문.

경고

이 문은 관련 없는 구문이므로 마이그레이션에서 제거되었습니다. 즉, Snowflake에서는 필요하지 않습니다.**

설명

문을 INSERT ... SELECT 사용할 오류를 로그에 기록하는 문입니다. 다음 설명서 를 참조하십시오.

샘플 소스 패턴

LOGGING ERRORS

이 예제에서는 LOGGING ERRORS 가 관련 구문이 아니므로 제거되었습니다. 이 구문은 Snowflake에서 필수가 아닙니다.

Teradata
 INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ERRORS;
Copy
Snowflake
INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;

LOGGING ALL ERRORS

이 예제에서는 LOGGING ALL ERRORS 가 관련 구문이 아니므로 제거되었음을 알 수 있습니다. 이 구문은 Snowflake에서 필수가 아닙니다.

Teradata
 INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ALL ERRORS;
Copy
Snowflake
 INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
Copy

LOGGING ERRORS WITH NO LIMIT

이 예제에서는 LOGGING ERRORS WITH NO LIMIT 가 관련 구문이 아니므로 제거되었음을 알 수 있습니다. 이 구문은 Snowflake에서 필수가 아닙니다.

Teradata
 INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ERRORS WITH NO LIMIT;
Copy
Snowflake
 INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
Copy

LOGGING ERRORS WITH LIMIT OF

이 예제에서는 LOGGING ERRORS WITH LIMIT OF 가 관련 구문이 아니므로 제거되었음을 알 수 있습니다. 이 구문은 Snowflake에서 필수가 아닙니다.

Teradata
 INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ERRORS WITH LIMIT OF 100;
Copy
Snowflake
 INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
Copy

알려진 문제

문제가 발견되지 않았습니다.

관련 EWIs

관련 EWIs 없음.

Select 문

Select 문 참조

Snowflake는 몇 가지 예외를 제외하고 Teradata의 SELECT 구문을 지원합니다. 기본적으로 SEL 약어는 지원하지 않습니다.​

Teradata

Sel

SEL DISTINCT col1, col2 FROM table1
Copy

Snowflake

Select

SELECT DISTINCT col1,
col2 FROM
table1;
Copy

Teradata는 별칭을 선언하기 전에 참조하는 기능을 지원하지만, Snowflake는 지원하지 않습니다. 이 시나리오의 변환은 참조된 열을 가져와서 참조하는 열 이름의 별칭을 변경하는 것입니다.

Teradata

Alias

SELECT
my_val, sum(col1),
col2 AS my_val FROM table1
Copy

Snowflake

Alias

SELECT
my_val,
SUM(col1),
col2 AS my_val FROM
table1;
Copy

제거된 절 옵션

다음 절 옵션은 Snowflake와 관련이 없으므로 마이그레이션 중에 제거됩니다.

Teradata

Snowflake

Expand on

지원 안 됨

Normalize

지원 안 됨

With check option (Query)

지원 안 됨

Known Issues

1. SEL abbreviation unsupported

이 약어는 Snowflake에서 지원되지 않지만, SELECT 로 변경하면 올바르게 변환됩니다.

관련 EWIs

관련 EWIs 없음.

ANY 조건자

경고

이는 현재 진행 중인 작업으로 향후 변경 사항이 적용될 수 있습니다.

설명

Teradata에서는 비교 작업 또는 IN/NOT IN 조건자에서 정량화가 가능합니다. 식과 하위 쿼리에서 반환된 값 세트의 1개 이상의 값을 비교하면 true입니다. 자세한 내용은 다음 Teradata 설명서 를 검토하십시오.

Teradata 구문

 { expression quantifier ( literal [ {, | OR} ... ] ) |
  { expression | ( expression [,...] ) } quantifier ( subquery )
}
Copy

여기서 한정자:

 { comparison_operator [ NOT ] IN } { ALL |ANY | SOME }
Copy

Snowflake 구문

SuccessPlaceholder

하위 쿼리 형식에서 IN 은 = ANY 와 같고 NOT IN 은 <>ALL 과 같습니다. 자세한 내용은 다음 Snowflake 설명서 를 참조하십시오.

개별 값을 비교하려면:

 <value> [ NOT ] IN ( <value_1> [ , <value_2> ...  ] )
Copy

row constructors(괄호로 묶인 값 목록)를 비교하려면:

 ( <value_A> [, <value_B> ... ] ) [ NOT ] IN (  ( <value_1> [ , <value_2> ... ] )  [ , ( <value_3> [ , <value_4> ... ] )  ...  ]  )
Copy

값을 하위 쿼리에서 반환된 값과 비교하려면:

 <value> [ NOT ] IN ( <subquery> )
Copy

샘플 소스 패턴

샘플 데이터

Teradata
쿼리
 CREATE TABLE Employee (
    EmpNo INT,
    Name VARCHAR(100),
    DeptNo INT
);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (1, 'Alice', 100);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (2, 'Bob', 300);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (3, 'Charlie', 500);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (4, 'David', 200);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (5, 'Eve', 100);
Copy
Snowflake
쿼리
 CREATE OR REPLACE TABLE Employee (
    EmpNo INT,
    Name VARCHAR(100),
    DeptNo INT
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "teradata",  "convertedOn": "01/14/2025",  "domain": "test" }}'
;

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (1, 'Alice', 100);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (2, 'Bob', 300);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (3, 'Charlie', 500);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (4, 'David', 200);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (5, 'Eve', 100);
Copy

WHERE 절에서 ANY 조건과 동일

Teradata

입력
 SELECT DeptNo
FROM Employee
WHERE DeptNo = ANY(100,300,500) ;
Copy
출력

DeptNo

100

500

100

300

Snowflake

입력
 SELECT DeptNo
FROM Employee
WHERE DeptNo IN(100,300,500) ;
Copy
출력

DeptNo

100

500

100

300

WHERE 절의 기타 비교 연산자

다른 비교 연산자가 있는 경우 필수 하위 쿼리를 추가하는 것이 이에 상응하는 변환입니다.

Teradata

입력
 SELECT Name, DeptNo
FROM Employee
WHERE DeptNo < ANY(100,300,500) ;
Copy
출력

이름

DeptNo

Eve

100

Alice

100

David

200

Bob

300

Snowflake

입력
 SELECT Name, DeptNo
FROM Employee
WHERE DeptNo < ANY 
(SELECT DeptNo
FROM Employee
WHERE DeptNo > 100
OR DeptNo > 300
OR DeptNo > 500);
Copy
출력

NAME

DEPTNO

Alice

100

Eve

100

Bob

300

David

200

WHERE 절의 IN ANY

Teradata

입력
 SELECT DeptNo
FROM Employee
WHERE DeptNo IN ANY(100,300,500) ;
Copy
출력

DeptNo

100

500

100

300

Snowflake

입력
 SELECT DeptNo
FROM Employee
WHERE DeptNo IN(100,300,500) ;
Copy
출력

DeptNo

100

500

100

300

WHERE 절의 NOT IN ALL

Teradata

입력
 SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN ALL(100, 200);
Copy
출력

이름

DeptNo

Charlie

500

Bob

300

Snowflake

입력
 SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN (100, 200);
Copy
출력

이름

DeptNo

Charlie

500

Bob

300

Known Issues

WHERE 절의 NOT IN ANY

Teradata

입력
 SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN ANY(100, 200);
Copy
출력

이름

DeptNo

Eve

100

Charlie

500

Alice

100

David

200

Bob

300

Snowflake

입력
 SELECT Name, DeptNo
FROM Employee
WHERE DeptNo IN (100, 200)
   OR DeptNo NOT IN (100, 200);
Copy
출력

이름

DeptNo

Eve

100

Charlie

500

Alice

100

David

200

Bob

300

관련 EWIs

관련 EWIs 없음.

Expand On 절

Teradata Expand On 기능을 Snowflake로 변환하기 위한 변환 참조

설명

Expand On 절은 기간 데이터 타입을 가진 열을 확장하여 입력 행의 기간 값을 기반으로 일반 시계열 행을 생성합니다. Expand On 절에 대한 자세한 내용은 Teradata 설명서 를 참조하십시오.

샘플 소스 패턴

참고

출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.

샘플 데이터

Teradata
 CREATE TABLE table1 (id INTEGER, pd PERIOD (TIMESTAMP));

INSERT INTO
    table1
VALUES
    (
        1,
        PERIOD(
            TIMESTAMP '2022-05-23 10:15:20.00009',
            TIMESTAMP '2022-05-23 10:15:25.000012'
        )
    );
Copy
Snowflake
 CREATE OR REPLACE TABLE table1 (
    id INTEGER,
    pd VARCHAR(58) !!!RESOLVE EWI!!! /*** SSC-EWI-TD0053 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/!!!
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;

INSERT INTO table1
VALUES (
1, PUBLIC.PERIOD_UDF(
            TIMESTAMP '2022-05-23 10:15:20.00009',
            TIMESTAMP '2022-05-23 10:15:25.000012'
        ) !!!RESOLVE EWI!!! /*** SSC-EWI-TD0053 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/!!!);
Copy

Expand On 절

기간 열을 초 단위로 확장하고 싶다고 가정해 보겠습니다. 이 확장 절에는 앵커 기간 확장 및 간격 리터럴 확장이 있습니다.

앵커 기간 확장
Teradata
 SELECT
    id,
    BEGIN(bg)
FROM
    table1 EXPAND ON pd AS bg BY ANCHOR ANCHOR_SECOND;
Copy
결과

id

BEGIN (bg)

1

2022-05-23 10:15:21.0000

1

2022-05-23 10:15:22.0000

1

2022-05-23 10:15:23.0000

1

2022-05-23 10:15:24.0000

1

2022-05-23 10:15:25.0000

Snowflake는 Expand On을 지원하지 않습니다. 동일한 결과와 기능을 재현하기 위해 Teradata SQL 코드는 CTE 블록에 포함되며, EXPAND_ON_UDFTABLE 함수를 사용하여 여러 행을 반환하는 FLATTEN 함수, ROW_COUNT_UDFDIFF_TTIME_PERIOD_UDF 를 사용하여 필요한 행 수를 표시하고 VALUE 를 반환하여 EXPAND_ON_UDF 가 다른 정규 시계열을 계산할 수 있도록 도와줍니다. 이 CTE 블록은 Expand On 절에서와 동일한 확장 열 별칭을 반환하므로 모든 기간 데이터 타입 사용에서 결과를 사용할 수 있습니다.

Snowflake
 WITH ExpandOnCTE AS
(
    SELECT
        PUBLIC.EXPAND_ON_UDF('ANCHOR_SECOND', VALUE, pd) bg
    FROM
        table1,
        TABLE(FLATTEN(PUBLIC.ROW_COUNT_UDF(PUBLIC.DIFF_TIME_PERIOD_UDF('ANCHOR_SECOND', pd))))
)
SELECT
    id,
    PUBLIC.PERIOD_BEGIN_UDF(bg) !!!RESOLVE EWI!!! /*** SSC-EWI-TD0053 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/!!!
FROM
    table1,
    ExpandOnCTE;
Copy
결과

id

PERIOD_BEGIN_UDF(bg)

1

2022-05-23 10:15:21.0000

1

2022-05-23 10:15:22.0000

1

2022-05-23 10:15:23.0000

1

2022-05-23 10:15:24.0000

1

2022-05-23 10:15:25.0000

Known Issues

Expand On 절은 간격 리터럴 확장을 사용할 수 있으며, 이 경우 SnowConvert AI는 이 변환이 계획되어 있다는 오류를 추가합니다.

간격 리터럴 확장

Teradata
 SELECT
    id,
    BEGIN(bg)
FROM
    table1 EXPAND ON pd AS bg BY INTERVAL '1' SECOND;
Copy
결과

id

BEGIN (bg)

1

2022-05-23 10:15:20.0000

1

2022-05-23 10:15:21.0000

1

2022-05-23 10:15:22.0000

1

2022-05-23 10:15:23.0000

1

2022-05-23 10:15:24.0000

Snowflake
 SELECT
    id,
    PUBLIC.PERIOD_BEGIN_UDF(bg) !!!RESOLVE EWI!!! /*** SSC-EWI-TD0053 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/!!!
FROM
    table1
!!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'EXPAND ON' NODE ***/!!!
EXPAND ON pd AS bg BY INTERVAL '1' SECOND;
Copy

관련 EWIs

  1. SSC-EWI-0073: 보류 중 함수 동등성 검토.

  2. SSC-EWI-TD0053: Snowflake는 기간 데이터 타입을 지원하지 않으며, 모든 기간은 대신 varchar로 처리됩니다.

Normalize

Teradata Normalize 기능을 Snowflake로 변환하기 위한 변환 참조

설명

NORMALIZE 는 첫 번째 기간 열의 기간 값이 서로 일치하거나 겹치는 경우 결합하여 개별 기간 값을 포괄하는 기간을 형성하도록 지정합니다. 정규화 절에 대한 자세한 내용은 Teradata 설명서 를 참조하십시오.

샘플 소스 패턴

참고

출력 코드의 일부 부분은 명확성을 위해 생략되었습니다.

샘플 데이터

Teradata
 CREATE TABLE project (
    emp_id INTEGER,
    project_name VARCHAR(20),
    dept_id INTEGER,
    duration PERIOD(DATE)
);

INSERT INTO project
VALUES
    (
        10,
        'First Phase',
        1000,
        PERIOD(DATE '2010-01-10', DATE '2010-03-20')
    );

INSERT INTO project
VALUES
    (
        10,
        'First Phase',
        2000,
        PERIOD(DATE '2010-03-20', DATE '2010-07-15')
    );

INSERT INTO project
VALUES
    (
        10,
        'Second Phase',
        2000,
        PERIOD(DATE '2010-06-15', DATE '2010-08-18')
    );

INSERT INTO project
VALUES
    (
        20,
        'First Phase',
        2000,
        PERIOD(DATE '2010-03-10', DATE '2010-07-20')
    );

INSERT INTO project
VALUES
    (
        20,
        'Second Phase',
        1000,
        PERIOD(DATE '2020-05-10', DATE '2020-09-20')
    );
Copy
Snowflake
 CREATE OR REPLACE TABLE project (
    emp_id INTEGER,
    project_name VARCHAR(20),
    dept_id INTEGER,
    duration VARCHAR(24) !!!RESOLVE EWI!!! /*** SSC-EWI-TD0053 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/!!!
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;

INSERT INTO project
VALUES (
10,
        'First Phase',
        1000, PUBLIC.PERIOD_UDF(DATE '2010-01-10', DATE '2010-03-20') !!!RESOLVE EWI!!! /*** SSC-EWI-TD0053 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/!!!);

INSERT INTO project
VALUES (
10,
        'First Phase',
        2000, PUBLIC.PERIOD_UDF(DATE '2010-03-20', DATE '2010-07-15') !!!RESOLVE EWI!!! /*** SSC-EWI-TD0053 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/!!!);

INSERT INTO project
VALUES (
10,
        'Second Phase',
        2000, PUBLIC.PERIOD_UDF(DATE '2010-06-15', DATE '2010-08-18') !!!RESOLVE EWI!!! /*** SSC-EWI-TD0053 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/!!!);

INSERT INTO project
VALUES (
20,
        'First Phase',
        2000, PUBLIC.PERIOD_UDF(DATE '2010-03-10', DATE '2010-07-20') !!!RESOLVE EWI!!! /*** SSC-EWI-TD0053 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/!!!);

INSERT INTO project
VALUES (
20,
        'Second Phase',
        1000, PUBLIC.PERIOD_UDF(DATE '2020-05-10', DATE '2020-09-20') !!!RESOLVE EWI!!! /*** SSC-EWI-TD0053 - SNOWFLAKE DOES NOT SUPPORT THE PERIOD DATATYPE, ALL PERIODS ARE HANDLED AS VARCHAR INSTEAD ***/!!!);
Copy

정규화 절

직원 ID와 함께 정규화 절을 사용한다고 가정해 보겠습니다.

Teradata
 SELECT
    NORMALIZE emp_id,
    duration
FROM
    project;
Copy
결과

EMP_ID

DURATION

20

(2010-03-10, 2010-07-20)

10

(2010-01-10, 2010-08-18)

20

(2020-05-10, 2010-09-20)

Snowflake
 !!!RESOLVE EWI!!! /*** SSC-EWI-TD0079 - THE REQUIRED PERIOD TYPE COLUMN WAS NOT FOUND ***/!!!
WITH NormalizeCTE AS
(
    SELECT
        T1.*,
        SUM(GroupStartFlag)
        OVER (
        PARTITION BY
            emp_id, duration
        ORDER BY
            PeriodColumn_begin
        ROWS UNBOUNDED PRECEDING) GroupID
    FROM
        (
            SELECT
                emp_id,
                duration,
                PUBLIC.PERIOD_BEGIN_UDF(PeriodColumn) PeriodColumn_begin,
                PUBLIC.PERIOD_END_UDF(PeriodColumn) PeriodColumn_end,
                (CASE
                    WHEN PeriodColumn_begin <= LAG(PeriodColumn_end)
                    OVER (
                    PARTITION BY
                        emp_id, duration
                    ORDER BY
                        PeriodColumn_begin,
                        PeriodColumn_end)
                        THEN 0
                    ELSE 1
                END) GroupStartFlag
            FROM
                project
        ) T1
)
SELECT
    emp_id,
    duration,
    PUBLIC.PERIOD_UDF(MIN(PeriodColumn_begin), MAX(PeriodColumn_end))
FROM
    NormalizeCTE
GROUP BY
    emp_id,
    duration,
    GroupID;
Copy
결과

EMP_ID

PUBLIC.PERIOD_UDF(MIN(START_DATE), MAX(END_DATE))

20

2020-05-10*2010-09-20

20

2010-03-10*2010-07-20

10

2010-01-10*2010-08-18

Known Issues

Normalize 절은 ON MEETS OR OVERLAPS, ON OVERLAPS 또는 ON OVERLAPS OR MEETS를 사용할 수 있습니다. 이러한 경우 SnowConvert AI는 이 변환이 향후에 계획되어 있다는 오류를 추가합니다.

Teradata

 SELECT NORMALIZE ON MEETS OR OVERLAPS emp_id, duration FROM table1;
Copy
Snowflake
 SELECT
       !!!RESOLVE EWI!!! /*** SSC-EWI-0073 - PENDING FUNCTIONAL EQUIVALENCE REVIEW FOR 'NORMALIZE SET QUANTIFIER' NODE ***/!!!
       NORMALIZE ON MEETS OR OVERLAPS emp_id,
duration FROM
table1;
Copy

관련 EWIs

  1. SSC-EWI-0073: 보류 중 함수 동등성 검토.

  2. SSC-EWI-TD0079: 필수 기간 유형 열을 찾을 수 없습니다.

  3. SSC-EWI-TD0053: Snowflake는 기간 데이터 타입을 지원하지 않으며, 모든 기간은 대신 varchar로 처리됩니다.

재설정 시기

설명

재설정 시 특정 조건에 따라 SQL 윈도우 함수가 작업할 파티션을 결정합니다. 조건이 true로 평가되면 기존 윈도우 파티션 내에 새 동적 하위 파티션이 생성됩니다. 재설정 시점에 대한 자세한 내용은 Teradata 설명서를 참조하십시오.

샘플 소스 패턴

샘플 데이터

Teradata

쿼리

CREATE TABLE account_balance
( 
  account_id INTEGER NOT NULL,
  month_id INTEGER,
  balance INTEGER
) 
UNIQUE PRIMARY INDEX (account_id, month_id);

INSERT INTO account_balance VALUES (1, 1, 60);
INSERT INTO account_balance VALUES (1, 2, 99);
INSERT INTO account_balance VALUES (1, 3, 94);
INSERT INTO account_balance VALUES (1, 4, 90);
INSERT INTO account_balance VALUES (1, 5, 80);
INSERT INTO account_balance VALUES (1, 6, 88);
INSERT INTO account_balance VALUES (1, 7, 90);
INSERT INTO account_balance VALUES (1, 8, 92);
INSERT INTO account_balance VALUES (1, 9, 10);
INSERT INTO account_balance VALUES (1, 10, 60);
INSERT INTO account_balance VALUES (1, 11, 80);
INSERT INTO account_balance VALUES (1, 12, 10);
Copy

결과

account_id

month_id

balance

1

1

60

1

2

99

1

3

94

1

4

90

1

5

80

1

6

88

1

7

90

1

8

92

1

9

10

1

10

60

1

11

80

1

12

10

Snowflake

쿼리

CREATE OR REPLACE TABLE account_balance (
  account_id INTEGER NOT NULL,
  month_id INTEGER,
  balance INTEGER,
  UNIQUE (account_id, month_id)
)
COMMENT = '{"origin":"sf_sc","name":"snowconvert","version":{"major":1, "minor":0},{"attributes":{"component":"teradata"}}'
;

INSERT INTO account_balance
VALUES (1, 1, 60);

INSERT INTO account_balance
VALUES (1, 2, 99);

INSERT INTO account_balance
VALUES (1, 3, 94);

INSERT INTO account_balance
VALUES (1, 4, 90);

INSERT INTO account_balance
VALUES (1, 5, 80);

INSERT INTO account_balance
VALUES (1, 6, 88);

INSERT INTO account_balance
VALUES (1, 7, 90);

INSERT INTO account_balance
VALUES (1, 8, 92);

INSERT INTO account_balance
VALUES (1, 9, 10);

INSERT INTO account_balance
VALUES (1, 10, 60);

INSERT INTO account_balance
VALUES (1, 11, 80);

INSERT INTO account_balance
VALUES (1, 12, 10);
Copy

결과

account_id

month_id

balance

1

1

60

1

2

99

1

3

94

1

4

90

1

5

80

1

6

88

1

7

90

1

8

92

1

9

10

1

10

60

1

11

80

1

12

10

재설정 시기

각 계정에 대해 연속적인 월별 잔액 증가 시퀀스를 분석하고 싶다고 가정해 보겠습니다. 한 달 잔액이 전월 잔액보다 적거나 같으면 카운터를 0으로 재설정하고 다시 시작해야 한다는 요구 사항이 있습니다.

이 데이터를 분석하기 위해 Teradata SQL 은 다음과 같이 중첩 집계 및 Reset When 문이 포함된 윈도우 함수를 사용합니다.

Teradata

쿼리

SELECT 
   account_id, 
   month_id, 
   balance, 
   (
     ROW_NUMBER() OVER (
       PARTITION BY account_id 
       ORDER BY 
         month_id RESET WHEN balance <= SUM(balance) OVER (
           PARTITION BY account_id 
           ORDER BY month_id
           ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING
         )
     ) -1
   ) AS balance_increase 
FROM account_balance 
ORDER BY 1, 2;
Copy

결과

account_idmonth_idbalancebalance_increase
11600
12991
13940
14900
15800
16881
17902
18923
19100
110601
111802
112100
Snowflake

Snowflake는 윈도우 함수에서 Reset When 절을 지원하지 않습니다. 동일한 결과를 재현하려면 다음과 같이 기본 SQL 구문과 중첩된 하위 쿼리를 사용하여 Teradata SQL 코드를 변환해야 합니다.

쿼리

SELECT
   account_id,
   month_id,
   balance,
   (
     ROW_NUMBER() OVER (
   PARTITION BY
      account_id, new_dynamic_part
   ORDER BY
         month_id
     ) -1
   ) AS balance_increase
FROM
   (
      SELECT
   account_id,
   month_id,
   balance,
   previous_value,
   SUM(dynamic_part) OVER (
           PARTITION BY account_id
           ORDER BY month_id
   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
         ) AS new_dynamic_part
      FROM
   (
      SELECT
         account_id,
         month_id,
         balance,
         SUM(balance) OVER (
                 PARTITION BY account_id
                 ORDER BY month_id
                 ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING
               ) AS previous_value,
         (CASE
            WHEN balance <= previous_value
               THEN 1
            ELSE 0
         END) AS dynamic_part
      FROM
         account_balance
   )
   )
ORDER BY 1, 2;
Copy

결과

account_idmonth_idbalancebalance_increase
11600
12991
13940
14900
15800
16881
17902
18923
19100
110601
111802
112100

Snowflake에서 언제 재설정 기능을 지원하려면 2개의 중첩된 하위 쿼리가 필요합니다.

내부 하위 쿼리에서 동적 파티션 표시기(dynamic_part)가 생성되어 채워집니다. 한 달의 잔액이 전월 잔액보다 작거나 같으면 dynamic_part가 1로 설정되고, 그렇지 않으면 0으로 설정됩니다.

다음 레이어에서는 SUM 윈도우 함수의 결과로 new_dynamic_part 특성이 생성됩니다.

마지막으로, 기존 파티션 특성(account_id)에 새 파티션 특성(동적 파티션)으로 new_dynamic_part를 추가하고 Teradata에서와 동일한 ROW_NUMBER() 윈도우 함수를 적용합니다.

이러한 변경 후 Snowflake는 Teradata와 동일한 출력을 생성합니다.

조건부 윈도우 함수가 열인 경우 재설정하기

위와 동일한 예제이지만, 이제 RESET WHEN 조건에 사용된 윈도우 함수가 previous 라는 열로 정의된다는 점을 예외로 합니다. 이 변형에서는 이전 예제에서와 같이 previous_value 를 정의할 필요가 없으므로 변환이 약간 변경됩니다. 동일한 해결 방법입니다.

Teradata

쿼리

SELECT
   account_id,
   month_id,
   balance,
   SUM(balance) OVER (
           PARTITION BY account_id
           ORDER BY month_id
           ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING
         ) AS previous,
   (
     ROW_NUMBER() OVER (
       PARTITION BY account_id
       ORDER BY
         month_id RESET WHEN balance <= previous
     )
   ) AS balance_increase
FROM account_balance
ORDER BY 1, 2;
Copy

결과

account_idmonth_idbalancepreviousbalance_increase
11600
1299601
1394990
1490940
1580900
1688801
1790882
1892903
1910920
11060101
11180602
11210800
Snowflake

쿼리

SELECT
   account_id,
   month_id,
   balance,
   SUM(balance) OVER (
           PARTITION BY account_id
           ORDER BY month_id
           ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING
         ) AS previous,
   (
     ROW_NUMBER() OVER (
   PARTITION BY
      account_id, new_dynamic_part
   ORDER BY
         month_id
     )
   ) AS balance_increase
FROM
   (
      SELECT
   account_id,
   month_id,
   balance,
   SUM(balance) OVER (
           PARTITION BY account_id
           ORDER BY month_id
           ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING
         ) AS previous,
   SUM(dynamic_part) OVER (
           PARTITION BY account_id
           ORDER BY month_id
   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
         ) AS new_dynamic_part
      FROM
   (
      SELECT
         account_id,
         month_id,
         balance,
         SUM(balance) OVER (
                 PARTITION BY account_id
                 ORDER BY month_id
                 ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING
               ) AS previous,
         (CASE
            WHEN balance <= previous
               THEN 1
            ELSE 0
         END) AS dynamic_part
      FROM
         account_balance
   )
   )
ORDER BY 1, 2;
Copy

제목 없음

account_idmonth_idbalancepreviousbalance_increase
11600
1299601
1394990
1490940
1580900
1688801
1790882
1892903
1910920
11060101
11180602
11210800

Known Issues

RESET WHEN 절에는 조건과 같은 몇 가지 변형이 있을 수 있습니다. 현재, SnowConvert AI는 이진 조건(<=, >=, <> 또는 =)만 지원합니다. IS NOT NULL과 같은 다른 유형의 경우 다음 예와 같이 Snowflake에서 지원되지 않으므로 SnowConvert AI는 RESET WHEN 절을 제거하고 오류 메시지를 추가합니다.

Teradata

쿼리

SELECT
    account_id,
    month_id,
    balance,
    ROW_NUMBER() OVER (
        PARTITION BY account_id
        ORDER BY month_id
        RESET WHEN balance IS NOT NULL
        ROWS UNBOUNDED PRECEDING
    ) as balance_increase
FROM account_balance
ORDER BY 1,2;
Copy

Snowflake

쿼리

SELECT
    account_id,
    month_id,
    balance,
    ROW_NUMBER() OVER (
        PARTITION BY account_id
    !!!RESOLVE EWI!!! /*** SSC-EWI-TD0077 - RESET WHEN CLAUSE IS NOT SUPPORTED IN THIS SCENARIO DUE TO ITS CONDITION ***/!!!
        ORDER BY month_id
        ROWS UNBOUNDED PRECEDING
    ) as balance_increase
FROM
    account_balance
ORDER BY 1,2;
Copy

관련 EWIs

  • SSC-EWI-TD0077: RESET WHEN 절은 해당 조건으로 인해 이 시나리오에서 지원되지 않습니다.

SAMPLE 절

설명

Teradata의 SAMPLE 절은 처리할 행 수를 줄이며 1개 이상의 행 샘플을 분수 목록 또는 행 수 목록으로 반환합니다. 이 절은 SELECT 쿼리에서 사용됩니다. 자세한 내용은 다음 Teradata 설명서 를 검토하십시오.

Teradata 구문

SAMPLE
  [ WITH REPLACEMENT ]
  [ RANDOMIZED LOCALIZATION ]
  { { fraction_description | count_description } [,...] |
    when_clause ]
  }
Copy

Snowflake 구문

자세한 내용은 다음 Snowflake 설명서 를 참조하십시오. SAMPLETABLESAMPLE 은 동의어입니다.

SELECT ...
FROM ...
  { SAMPLE | TABLESAMPLE } [ samplingMethod ]
[ ... ]
Copy

여기서

samplingMethod ::= { 
{ BERNOULLI | ROW } ( { <probability> | <num> ROWS } ) |
{ SYSTEM | BLOCK } ( <probability> ) [ { REPEATABLE | SEED } ( <seed> ) ] }
Copy
  • Snowflake에서는 다음 키워드를 서로 바꿔서 사용할 수 있습니다.

    • SAMPLE | TABLESAMPLE

    • BERNOULLI | ROW

    • SYSTEM | BLOCK

    • REPEATABLE | SEED

다음 테이블을 검토하여 주요 차이점을 확인하십시오.

SAMPLE 동작

Teradata

Snowflake

확률별 샘플

분수 설명이라고도 합니다. 0,1에서 1 사이의 소수점이어야 합니다.

0에서 100 사이의 소수점 숫자입니다.

수정된 행 수

카운트 설명이라고도 합니다. 샘플링할 행의 수를 결정하는 양의 정수입니다.

테이블에서 샘플을 추출할 행 수(최대 1,000,000개)를 지정합니다. 0 (선택한 행이 없음)에서 1000000 사이의 정수일 수 있습니다.

반복 행

WITHREPLACEMENT 이라고 합니다. 테이블의 행 수보다 많은 샘플을 쿼리하는 데 사용됩니다.

REPEATABLE 또는 SEED 로 알려져 있습니다. 이는 쿼리를 결정적으로 생성하는 데 사용됩니다. 이는 각 쿼리 실행에 대해 동일한 행 세트가 동일하다는 것을 의미합니다.

샘플링 방법

ProportionalRANDOMIZED ALLOCATION.

BERNOULLI 또는 SYSTEM.

샘플 소스 패턴

샘플 데이터

Teradata

쿼리

CREATE TABLE Employee (
    EmpNo INT,
    Name VARCHAR(100),
    DeptNo INT
);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (1, 'Alice', 100);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (2, 'Bob', 300);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (3, 'Charlie', 500);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (4, 'David', 200);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (5, 'Eve', 100);
Copy
Snowflake

쿼리

CREATE OR REPLACE TABLE Employee (
    EmpNo INT,
    Name VARCHAR(100),
    DeptNo INT
)
COMMENT = '{ "origin": "sf_sc", "name": "snowconvert", "version": {  "major": 0,  "minor": 0,  "patch": "0" }, "attributes": {  "component": "teradata",  "convertedOn": "01/14/2025",  "domain": "test" }}'
;

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (1, 'Alice', 100);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (2, 'Bob', 300);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (3, 'Charlie', 500);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (4, 'David', 200);

INSERT INTO Employee (EmpNo, Name, DeptNo)
VALUES (5, 'Eve', 100);
Copy

SAMPLE 절

수정된 행 수

이 예제에서 행 수는 수정된 수이지만 각 실행마다 반드시 동일한 결과가 나오는 것은 아닙니다.

Teradata

입력

SELECT * FROM Employee SAMPLE 2;
Copy

출력 2개의 행.

Snowflake

입력

SELECT * FROM Employee SAMPLE (2 ROWS);
Copy

출력 2개의 행.

확률에 따른 행 수

이 옵션은 설정된 확률에 따라 다양한 행을 반환합니다.

Teradata

입력

SELECT * FROM Employee SAMPLE 0.25;
Copy

출력 각 행에 대한 확률의 25%: 1개의 출력 행.

Snowflake

입력

SELECT * FROM Employee SAMPLE (25);
Copy

출력 각 행에 대한 확률의 25%: 1개의 출력 행.

Known Issues

교체가 가능한 행 수 수정

이 옵션은 수정된 수의 행을 반환하며 행을 반복할 수 있습니다. Snowflake에서는 테이블의 행 수보다 많은 샘플을 요청할 수 없습니다.

Teradata 샘플

입력

SELECT * FROM Employee SAMPLE WITH REPLACEMENT 8;
Copy

출력

EmpNo

이름

DeptNo

5

Eve

100

5

Eve

100

5

Eve

100

4

David

200

4

David

200

3

Charlie

500

1

Alice

100

1

Alice

100

조건부 샘플링

Snowflake에는 조건부 샘플링이 없습니다. 이는 CTE를 사용하여 달성할 수 있습니다.

Teradata 샘플

입력

SELECT * FROM employee
SAMPLE WHEN DeptNo > 100 then 0.9 
ELSE 0.1 END;
Copy

출력

EmpNo

이름

DeptNo

3

Charlie

500

4

David

200

2

Bob

300

관련 EWIs

SSC-EWI-0021: Snowflake에서 지원되지 않는 구문입니다.