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
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;
既知の問題¶
1.DEL 省略形がサポートされていません¶
省略形はSnowflakeではサポートされていませんが、 DELETE に変更することで正しく翻訳されます。
集合演算子¶
注釈
わかりやすくするため、出力コードの一部を省略しています。
セット演算子 を参照してください。
TeradataとSnowflakeの両方のセット演算子は同じ構文で、 INTERSECT ALL
の句 ALL
を除いて、 EXCEPT
、 INTERSECT
、 UNION
のシナリオをサポートしています。これは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;
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;
既知の問題¶
1.INTERSECT ALL がサポートされていません¶
Snowflakeでは INTERSECT ALL はサポートされておらず、 ALL の部分がコメントされます。
関連 EWIs¶
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';
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';
関連 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;
Snowflake
WITH RECURSIVE n1(c1) AS
(
SELECT
c1,
c3 from
t2, n1
),
n2(c2) AS
(
SELECT
c2 from
tablex
)
SELECT
* FROM
t1;
既知の問題¶
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'));
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))));
既知の問題¶
問題は見つかりませんでした。
関連 EWIs ¶
関連 EWIs はありません。
LOGGING ERRORS¶
注釈
わかりやすくするため、出力コードの一部を省略しています。
注釈
関連性のないステートメント。
警告
このステートメントは 関連性のない構文であるため、 移行から削除されていることに注意してください。 Snowflakeでは必要ないということです。
説明¶
ステートメントを INSERT...SELECT
として使用する際にエラーをログに記録するステートメント。以下の ドキュメント を参照してください。
サンプルソースパターン¶
LOGGING ERRORS¶
この例では、 LOGGING ERRORS
は関係ない構文なので削除されていることに注意してください。構文はSnowflakeでは必須ではありません。
INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ERRORS;
INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
LOGGING ALL ERRORS¶
この例では、 LOGGING ALL ERRORS
は関係ない構文なので削除されていることに注意してください。構文はSnowflakeでは必須ではありません。
INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ALL ERRORS;
INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
LOGGING ERRORS WITH NO LIMIT¶
この例では、 LOGGING ERRORS WITH NO LIMIT
は関係ない構文なので削除されていることに注意してください。構文はSnowflakeでは必須ではありません。
INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ERRORS WITH NO LIMIT;
INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
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;
INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
既知の問題¶
問題は見つかりませんでした。
関連 EWIs ¶
関連 EWIs はありません。
ステートメントを選択¶
ステートメントを選択 を見る
Snowflakeは、いくつかの例外を除き、Teradataの SELECT
構文をサポートしています。主に、 SEL
の省略形をサポートしていません。
Teradata
SEL DISTINCT col1, col2 FROM table1
Snowflake
SELECT DISTINCT col1,
col2 FROM
table1;
Teradataは宣言前のエイリアスの参照をサポートしていますが、Snowflakeはサポートしていません。このシナリオの変換は、参照される列を取り出し、その列が参照する列名のエイリアスを変更することです。
Teradata
SELECT
my_val, sum(col1),
col2 AS my_val FROM table1
Snowflake
SELECT
my_val,
sum(col1),
col2 AS my_val FROM
table1;
削除された句オプション¶
以下の句オプションは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 )
}
Where量指定子:
{ comparison_operator [ NOT ] IN } { ALL |ANY | SOME }
Snowflake構文
サブクエリ形式では、 IN は = ANY
と等価であり、 NOT IN は <> ALL
と等価です。詳細については、以下の Snowflakeドキュメント を参照してください。
個々の値を比較するには、
<value> [ NOT ] IN ( <value_1> [ , <value_2> ... ] )
row constructors (括弧で括られた値のリスト)を比較するには、
( <value_A> [, <value_B> ... ] ) [ NOT ] IN ( ( <value_1> [ , <value_2> ... ] ) [ , ( <value_3> [ , <value_4> ... ] ) ... ] )
値をサブクエリによって返される値と比較するには、
<value> [ NOT ] IN ( <subquery> )
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);
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);
WHERE 句における等しい ANY 述語
Teradata
SELECT DeptNo
FROM Employee
WHERE DeptNo = ANY(100,300,500) ;
DeptNo |
---|
100 |
500 |
100 |
300 |
Snowflake
SELECT DeptNo
FROM Employee
WHERE DeptNo IN(100,300,500) ;
DeptNo |
---|
100 |
500 |
100 |
300 |
WHERE 句の他の比較演算子
他の比較演算子がある場合、同等の変換は、必要なロジックを持つサブクエリを追加することです。
Teradata
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo < ANY(100,300,500) ;
名前 |
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);
NAME |
DEPTNO |
---|---|
アリス |
100 |
イブ |
100 |
ボブ |
300 |
デイビッド |
200 |
WHERE 句内の IN ANY
Teradata
SELECT DeptNo
FROM Employee
WHERE DeptNo IN ANY(100,300,500) ;
DeptNo |
---|
100 |
500 |
100 |
300 |
Snowflake
SELECT DeptNo
FROM Employee
WHERE DeptNo IN(100,300,500) ;
DeptNo |
---|
100 |
500 |
100 |
300 |
WHERE 句内の NOT IN ALL
Teradata
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN ALL(100, 200);
名前 |
DeptNo |
---|---|
チャーリー |
500 |
ボブ |
300 |
Snowflake
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN (100, 200);
名前 |
DeptNo |
---|---|
チャーリー |
500 |
ボブ |
300 |
Known Issues
WHERE 句内の NOT IN ANY
Teradata
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN ANY(100, 200);
名前 |
DeptNo |
---|---|
イブ |
100 |
チャーリー |
500 |
アリス |
100 |
デイビッド |
200 |
ボブ |
300 |
Snowflake
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo IN (100, 200)
OR DeptNo NOT IN (100, 200);
名前 |
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'
)
);
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 ***/!!!);
Expand On句¶
期間列を秒単位で拡大するとします。このExpand On句には、アンカー期間拡大と間隔リテラル拡大があります。
アンカー期間拡大
SELECT
id,
BEGIN(bg)
FROM
table1 EXPAND ON pd AS bg BY ANCHOR ANCHOR_SECOND;
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;
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;
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;
関連 EWIs¶
SSC-EWI-0073: 機能同等性レビュー保留中。
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')
);
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 ***/!!!);
Normalize句¶
Normalize句を従業員IDで使用したいとします。
SELECT
NORMALIZE emp_id,
duration
FROM
project;
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;
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 OVERLAPS、 ON OVERLAPS または ON OVERLAPS OR MEETS を使用することができます。これらの場合、 SnowConvert は、この翻訳が将来的に予定されているというエラーを追加します。
SELECT NORMALIZE ON MEETS OR OVERLAPS emp_id, duration FROM table1;
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;
関連 EWIs¶
SSC-EWI-0073: 機能同等性レビュー保留中。
SSC-EWI-TD0079: 必要な期間タイプ列が見つかりませんでした。
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);
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);
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;
account_id | month_id | balance | balance_increase |
---|---|---|---|
1 | 1 | 60 | 0 |
1 | 2 | 99 | 1 |
1 | 3 | 94 | 0 |
1 | 4 | 90 | 0 |
1 | 5 | 80 | 0 |
1 | 6 | 88 | 1 |
1 | 7 | 90 | 2 |
1 | 8 | 92 | 3 |
1 | 9 | 10 | 0 |
1 | 10 | 60 | 1 |
1 | 11 | 80 | 2 |
1 | 12 | 10 | 0 |
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;
account_id | month_id | balance | balance_increase |
---|---|---|---|
1 | 1 | 60 | 0 |
1 | 2 | 99 | 1 |
1 | 3 | 94 | 0 |
1 | 4 | 90 | 0 |
1 | 5 | 80 | 0 |
1 | 6 | 88 | 1 |
1 | 7 | 90 | 2 |
1 | 8 | 92 | 3 |
1 | 9 | 10 | 0 |
1 | 10 | 60 | 1 |
1 | 11 | 80 | 2 |
1 | 12 | 10 | 0 |
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;
account_id | month_id | balance | previous | balance_increase |
---|---|---|---|---|
1 | 1 | 60 | 0 | |
1 | 2 | 99 | 60 | 1 |
1 | 3 | 94 | 99 | 0 |
1 | 4 | 90 | 94 | 0 |
1 | 5 | 80 | 90 | 0 |
1 | 6 | 88 | 80 | 1 |
1 | 7 | 90 | 88 | 2 |
1 | 8 | 92 | 90 | 3 |
1 | 9 | 10 | 92 | 0 |
1 | 10 | 60 | 10 | 1 |
1 | 11 | 80 | 60 | 2 |
1 | 12 | 10 | 80 | 0 |
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;
account_id | month_id | balance | previous | balance_increase |
---|---|---|---|---|
1 | 1 | 60 | 0 | |
1 | 2 | 99 | 60 | 1 |
1 | 3 | 94 | 99 | 0 |
1 | 4 | 90 | 94 | 0 |
1 | 5 | 80 | 90 | 0 |
1 | 6 | 88 | 80 | 1 |
1 | 7 | 90 | 88 | 2 |
1 | 8 | 92 | 90 | 3 |
1 | 9 | 10 | 92 | 0 |
1 | 10 | 60 | 10 | 1 |
1 | 11 | 80 | 60 | 2 |
1 | 12 | 10 | 80 | 0 |
既知の問題¶
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;
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;
関連 EWIs¶
SSC-EWI-TD0077: RESET WHEN 句はその条件のため、このシナリオではサポートされません。
SAMPLE 句¶
説明¶
Teradataの SAMPLE 句は、処理する行数を減らし、1つ以上の行のサンプルを端数のリストまたは行数のリストとして返します。この句は SELECT クエリで使用されます。詳細情報については、以下の Teradataドキュメント を参照してください。
Teradata構文
SAMPLE
[ WITH REPLACEMENT ]
[ RANDOMIZED LOCALIZATION ]
{ { fraction_description | count_description } [,...] |
when_clause ]
}
Snowflake構文
詳細情報については、以下の Snowflakeドキュメント を参照してください。 SAMPLE
と TABLESAMPLE
は同義です。
SELECT ...
FROM ...
{ SAMPLE | TABLESAMPLE } [ samplingMethod ]
[ ... ]
条件:
samplingMethod ::= {
{ BERNOULLI | ROW } ( { <probability> | <num> ROWS } ) |
{ SYSTEM | BLOCK } ( <probability> ) [ { REPEATABLE | SEED } ( <seed> ) ] }
Snowflakeでは、以下のキーワードは互換性があります。
SAMPLE | TABLESAMPLE
BERNOULLI | ROW
SYSTEM | BLOCK
REPEATABLE | SEED
以下のテーブルでキーの違いを確認してください。
SAMPLE 動作 |
Teradata |
Snowflake |
---|---|---|
確率によるサンプル |
分数の説明としても知られています。0,1から1の間の小数でなければなりません。 |
0から100までの小数点。 |
固定行数 |
カウントの説明としても知られています。サンプリングする行数を決める正の整数です。 |
テーブルからサンプルする行数(最大1,000,000)を指定します。 |
繰り返し行 |
これは |
|
サンプリング方法 |
Proportional および |
|
サンプルソースパターン¶
サンプルデータ¶
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);
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);
SAMPLE 句¶
固定行数
この例では、行数は一定ですが、各実行で同じ結果になるとは限らないことに注意してください。
Teradata
SELECT * FROM Employee SAMPLE 2;
2行。
Snowflake
SELECT * FROM Employee SAMPLE (2 ROWS);
2行。
確率に基づく行数
このオプションは、確率セットに応じてさまざまな行を返します。
Teradata
SELECT * FROM Employee SAMPLE 0.25;
各行の確率25%: 1出力行。
Snowflake
SELECT * FROM Employee SAMPLE (25);
各行の確率25%: 1出力行。
既知の問題¶
置換による固定行数¶
このオプションは固定行数を返し、行の繰り返しを許可します。Snowflakeでは、テーブルの行数以上のサンプルをリクエストすることはできません。
Teradataサンプル
SELECT * FROM Employee SAMPLE WITH REPLACEMENT 8;
EmpNo |
名前 |
DeptNo |
---|---|---|
5 |
イブ |
100 |
5 |
イブ |
100 |
5 |
イブ |
100 |
4 |
デイビッド |
200 |
4 |
デイビッド |
200 |
3 |
チャーリー |
500 |
1 |
アリス |
100 |
1 |
アリス |
100 |