SnowConvert: Teradata DML 문

Delete 문

Delete 문 참조

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

Teradata

 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 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 로 변경하면 올바르게 변환됩니다.

세트 연산자

참고

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

Set 연산자 참조

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

Teradata

 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

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

SELECT
LastName,
FirstName FROM
employees
INTERSECT
!!!RESOLVE EWI!!! /*** SSC-EWI-0040 - THE STATEMENT 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 문

Update 문 참조

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

Teradata

 -- Case 1, THERE IS A REFERENCE TO TABLE2 IN THE SET CLAUSE WITHOUT A FROM
 
 UPDATE CRASHDUMPS.TABLE1 i
 SET COLUMN4 = CRASHDUMPS.TABLE2.COLUMN3
 WHERE i.COLUMN1 = CRASHDUMPS.TABLE2.COLUMN1
 AND i.COLUMN3 = 'L';

 -- CASE 2, FORWARD ALIAS
 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

 -- Case 1, THERE IS A REFERENCE TO TABLE2 IN THE SET CLAUSE WITHOUT A FROM
UPDATE CRASHDUMPS.PUBLIC.TABLE1 AS i
SET i.COLUMN4 = CRASHDUMPS.TABLE2.COLUMN3
WHERE i.COLUMN1 = CRASHDUMPS.TABLE2.COLUMN1
AND i.COLUMN3 = 'L';

-- CASE 2, FORWARD ALIAS
UPDATE CRASHDUMPS.PUBLIC.TABLE1 AS i 
SET i.COLUMN4 = CRASHDUMPS.TABLE2.COLUMN3 FROM CRASHDUMPS.PUBLIC.TABLE2
WHERE i.COLUMN1 = CRASHDUMPS.TABLE2.COLUMN1
AND i.COLUMN3 = 'L';
Copy

관련 EWIs

관련 EWIs 없음.

With Modifier

수정자 포함 참조

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

WITH 호출 시퀀스에서 사이클이 감지된 경우, SSC-EWI-TD0077 의 예제에 설명된 대로 시퀀스를 변경하지 않고 원본 그대로 유지합니다. 아래 예에서는 n1과 n2라는 이름의 CTEs 가 2개 있으며, n1은 n2를 참조합니다. 그런 다음 n2를 해당 변환된 코드로 Snowflake에서 먼저 정의해야 합니다.

참고

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

Teradata

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

Snowflake

 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 문

참고

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

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에서 필수가 아닙니다.

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

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

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

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

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

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

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

알려진 문제

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

관련 EWIs

관련 EWIs 없음.

Select 문

Select 문 참조

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

Teradata

 SEL DISTINCT col1, col2 FROM table1
Copy

Snowflake

 SELECT DISTINCT col1,
col2 FROM
table1;
Copy

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

Teradata

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

Snowflake

 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 구문

하위 쿼리 형식에서 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

Sample Source Patterns

샘플 데이터

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

Related EWIs

관련 EWIs 없음.

Expand On 절

Description

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

Sample Source Patterns

참고

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

샘플 데이터
 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
 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 절

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

앵커 기간 확장

 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 절에서와 동일한 확장 열 별칭을 반환하므로 모든 기간 데이터 타입 사용에서 결과를 사용할 수 있습니다.

 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 는 이 변환이 계획되어 있음을 나타내는 오류를 추가합니다.

간격 리터럴 확장
 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

 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

설명

NORMALIZE 는 첫 번째 기간 열의 기간 값이 서로 일치하거나 겹치는 경우 결합하여 개별 기간 값을 포괄하는 기간을 형성하도록 지정합니다. 정규화 절에 대한 자세한 내용은 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
 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와 함께 정규화 절을 사용한다고 가정해 보겠습니다.

 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)

 !!!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 는 이 변환이 향후 계획되어 있음을 나타내는 오류를 추가합니다.

 SELECT NORMALIZE ON MEETS OR OVERLAPS emp_id, duration FROM table1;
Copy
 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 는 이진 조건(<=, >=, <> 또는 =)만 지원합니다. IS NOT NULL 과 같은 다른 유형의 경우 이는 Snowflake에서 지원되지 않기 때문에 SnowConvert 는 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