SnowConvert: Teradata DML ステートメント

ステートメントの削除

ステートメントの削除 を見る

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

既知の問題

1.DEL 省略形がサポートされていません

省略形はSnowflakeではサポートされていませんが、 DELETE に変更することで正しく翻訳されます。

集合演算子

注釈

わかりやすくするため、出力コードの一部を省略しています。

セット演算子 を参照してください。

TeradataとSnowflakeの両方のセット演算子は同じ構文で、 INTERSECT ALL の句 ALL を除いて、 EXCEPTINTERSECTUNION のシナリオをサポートしています。これはSnowflakeではサポートされていないため、変換後に 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

既知の問題

1.INTERSECT ALL がサポートされていません

Snowflakeでは INTERSECT ALL はサポートされておらず、 ALL の部分がコメントされます。

関連 EWIs

  1. SSC-EWI-0040: ステートメントがサポートされていません。

ステートメントの更新

ステートメントの更新 を見る

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 はありません。

修飾子付き

修飾子付き を見る

Snowflakeは、 CTEs (共通テーブル式)を複数持つ SELECT ステートメントで、Teradataの WITH 修飾子をサポートしています。Teradataは、 CTE の定義が宣言される前に参照されるかどうかに関係なく、どのような順序でもサポートしますが、Snowflakeでは、 CTE が別の CTE を呼び出す場合は、呼び出される前に定義する必要があります。次に、 WITH 内の変換された CTEs のシーケンスは、参照されていない CTEs、次に次の CTE を呼び出す CTE、というように並び替えられます。

WITH 呼び出しシーケンスでサイクルが検出された場合は、 SSC-EWI-TD0077の例に詳述されているように、シーケンスは変更されずに元の状態のままになります。以下の例では、n1とn2という名前の2つの CTEs があり、n1はn2を参照しています。その場合、Snowflakeではまずn2を対応する変換コードとして定義する必要があります。

注釈

わかりやすくするため、出力コードの一部を省略しています。

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

既知の問題

1.サイクルが見つかった場合、並べ替えは不可能

CTEs の参照が分析され、 CTEs の呼び出しの間にサイクルがある場合、 CTEs は順序付けされません。

関連 EWIs

関連 EWIs はありません。

ステートメントの挿入

注釈

わかりやすくするため、出力コードの一部を省略しています。

ステートメントの挿入 を見る

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 はありません。

ステートメントを選択

ステートメントを選択 を見る

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

拡大

サポート対象外

ノーマライズ

サポート対象外

チェックオプション付き(クエリ)

サポート対象外

既知の問題

1.SEL 省略形がサポートされていません

省略形はSnowflakeではサポートされていませんが、 SELECT に変更することで正しく翻訳されます。

関連 EWIs

関連 EWIs はありません。

ANY 述語

警告

これは進行中の作業であり、将来的に変更が加えられる可能性があります。

説明

Teradataでは、比較演算または IN/NOT IN 述語で定量化が可能です。式とサブクエリが返す値のセット内の少なくとも1つの値の比較が真です。詳細情報については、以下の Teradataドキュメント を参照してください。

Teradata構文

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

Where量指定子:

 { 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

イブ

100

アリス

100

デイビッド

200

ボブ

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

アリス

100

イブ

100

ボブ

300

デイビッド

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

チャーリー

500

ボブ

300

Snowflake

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

名前

DeptNo

チャーリー

500

ボブ

300

Known Issues

WHERE 句内の NOT IN ANY

Teradata

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

名前

DeptNo

イブ

100

チャーリー

500

アリス

100

デイビッド

200

ボブ

300

Snowflake

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

名前

DeptNo

イブ

100

チャーリー

500

アリス

100

デイビッド

200

ボブ

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句

期間列を秒単位で拡大するとします。この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_UDF および TABLE 関数を使用し、 FLATTEN 関数を使用して複数行を返し、 ROW_COUNT_UDF および DIFF_TTIME_PERIOD_UDF を使用して必要な行数を示し、 VALUE を返して、EXPAND_ON_UDF が異なる定期的な時系列を計算できるようにします。この CTE ブロックはExpand On句と同じexpand列エイリアスを返すので、期間データ型のどのような使用法でも結果を使用できます。

 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

既知の問題

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
Normalize句

Normalize句を従業員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

既知の問題

Normalize句には、 ON MEETS OR OVERLAPSON 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として処理されます。

Reset When

説明

Reset Whenは、 SQL ウィンドウ関数が動作するパーティションを、特定の条件に基づいて決定します。条件がTrueに評価されると、既存のウィンドウパーティション内に新しい動的サブパーティションが作成されます。Reset Whenの詳細情報については、 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

Reset When

各アカウントについて、毎月の連続した残高増加のシーケンスを分析したいとします。ある月の残高が前月の残高以下である場合、カウンターをゼロにリセットし、再スタートする必要があります。

このデータを分析するために、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句をサポートしていません。同じ結果を再現するには、Teradata SQL コードを、ネイティブ 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のReset When機能をサポートするには、2つのネストされたサブクエリが必要です。

内部サブクエリでは、動的パーティションインディケータ(dynamic_part)が作成され、入力されます。ある月の残高が前月の残高以下の場合、dynamic_partは1にセットされ、それ以外の場合、0にセットされます。

次のレイヤーでは、 SUM ウィンドウ関数の結果として、new_dynamic_part属性が生成されます。

最後に、既存のパーティション属性(account_id)に新しいパーティション属性(動的パーティション)としてnew_dynamic_partを追加し、Teradataと同じ ROW_NUMBER()ウィンドウ関数を適用します。

これらの変更後、SnowflakeはTeradataと同じ出力を生成します。

条件付きウィンドウ関数が列の場合のReset When

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

既知の問題

RESET WHEN 句は、その条件などいくつかのバリエーションがあります。現在、 SnowConvert はバイナリ条件(<=、>=、<>または=)のみをサポートしています。 IS NOT NULL のように他のタイプでは、 SnowConvert が RESET WHEN 句を削除し、Snowflakeではサポートされていないため、次の例のようにエラーメッセージが追加されます。

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 の間の任意の整数を指定できます。

繰り返し行

これは WITH REPLACEMENT として知られています。これは、テーブルの行数よりも多くのサンプルをクエリするために使用されます。

REPEATABLE または SEED として知られています。これはクエリを決定論的にするために使用されます。これは、クエリを実行するたびに同じ行のセットが同じになることを意味します。

サンプリング方法

Proportional および RANDOMIZED 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出力行。

既知の問題

置換による固定行数

このオプションは固定行数を返し、行の繰り返しを許可します。Snowflakeでは、テーブルの行数以上のサンプルをリクエストすることはできません。

Teradataサンプル

 SELECT * FROM Employee SAMPLE WITH REPLACEMENT 8;
Copy

EmpNo

名前

DeptNo

5

イブ

100

5

イブ

100

5

イブ

100

4

デイビッド

200

4

デイビッド

200

3

チャーリー

500

1

アリス

100

1

アリス

100