SnowConvert : Instruction DML Teradata¶
Instruction de suppression¶
Voir Instruction de suppression
Teradata prend en charge l’appel à plus d’une table dans la clauseFROM
, ce qui n’est pas le cas de Snowflake. Il est donc nécessaire d’utiliser la clauseUSING
pour faire référence aux tables supplémentaires impliquées dans la condition.
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;
Problèmes connus¶
1. DEL abbreviation unsupported¶
L’abréviation n’est pas prise en charge dans Snowflake mais elle est traduite correctement en la remplaçant par DELETE.
Opérateurs Set¶
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Les opérateurs d’ensemble dans Teradata et Snowflake ont la même syntaxe et supportent les scénarios EXCEPT
, INTERSECT
et UNION
à l’exception de la clause ALL
dans INTERSECT ALL
, qui n’est pas prise en charge dans Snowflake, ce qui fait qu’une partie de ALL
est un code commenté après la conversion.
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;
Problèmes connus¶
1. INTERSECT ALL unsupported¶
INTERSECT ALL n’est pas pris en charge dans Snowflake et la partie ALL sera commentée.
EWIs connexes¶
SSC-EWI-0040 : Instruction non prise en charge.
Instruction de mise à jour¶
Voir Instruction de mise à jour
Teradata prend en charge le référencement d’un alias avant qu’il ne soit déclaré, ce qui n’est pas le cas de Snowflake. La transformation pour ce scénario consiste à prendre la table référencée et à modifier l’alias du nom de la table à laquelle elle fait référence.
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 connexes¶
Pas d’EWIs connexes.
Avec modificateur¶
Voir Avec modificateur
Snowflake prend en charge le modificateur WITH
de Teradata sur une instruction SELECT qui a plusieurs CTEs
(Expressions de table communes). Teradata accepte n’importe quel ordre de définition de CTE, qu’elles soient référencées avant d’être déclarées ou non, mais Snowflake exige que si une CTE appelle une autre CTE, elle doit être définie avant d’être appelée. Ensuite, la séquence convertie des CTEs à l’intérieur de WITH sera réorganisée en CTEs non référencée, puis en CTE qui appelle la CTE suivante, et ainsi de suite.
Lorsqu’un cycle est détecté dans la séquence d’appel de WITH, il sera laissé tel quel, sans aucune modification de la séquence, comme indiqué dans un exemple de SSC-EWI-TD0077 Dans l’exemple ci-dessous, il y a deux CTEs nommées n1 et n2, le n1 se référant au n2. Dans ce cas, n2 doit d’abord être définie dans Snowflake comme le code converti correspondant.
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
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;
Problèmes connus¶
1. Impossible to reorder when cycles were found¶
Lorsque les références CTEs sont analysées et qu’il y a un cycle entre les appels des CTEs, la CTEs ne sera pas commandée.
EWIs connexes¶
Pas d’EWIs connexes.
Instruction d’insertion¶
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Dans Teradata, il existe une autre syntaxeINSERT
qui attribue la valeur de chaque colonne de table en ligne. Cette structure alternative nécessite une transformation spéciale pour être prise en charge dans Snowflake. L’affectation en ligne des valeurs est séparée et placée à l’intérieur de la partie VALUES(...)
de l’instruction Snowflake INSERT INTO
.
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))));
Problèmes connus ¶
Aucun problème n’a été constaté.
EWIs connexes ¶
Pas d’EWIs connexes.
LOGGING ERRORS¶
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Note
Instruction non pertinente.
Avertissement
Remarquez que cette instruction est retirée de la migration parce qu’il s’agit d’une syntaxe non pertinente. Cela signifie qu’elle n’est pas exigée dans Snowflake.
Description¶
Instruction pour journaliser les erreurs lors de l’utilisation d’instructions comme INSERT...SELECT.
Veuillez consulter la documentation suivante.
Modèles d’échantillons de sources¶
LOGGING ERRORS¶
Dans cet exemple, vous remarquerez que LOGGING ERRORS
a été supprimé car il ne s’agit pas d’une syntaxe pertinente. La syntaxe n’est pas exigée dans Snowflake.
INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ERRORS;
INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
LOGGING ALL ERRORS¶
Dans cet exemple, vous remarquerez que LOGGING ALL ERRORS
a été supprimé car il ne s’agit pas d’une syntaxe pertinente. La syntaxe n’est pas exigée dans 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¶
Dans cet exemple, vous remarquerez que LOGGING ERRORS WITH NO LIMIT
a été supprimé car il ne s’agit pas d’une syntaxe pertinente. La syntaxe n’est pas exigée dans 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¶
Dans cet exemple, vous remarquerez que LOGGING ERRORS WITH LIMIT OF
a été supprimé car il ne s’agit pas d’une syntaxe pertinente. La syntaxe n’est pas exigée dans Snowflake.
INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ERRORS WITH LIMIT OF 100;
INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
Problèmes connus ¶
Aucun problème n’a été constaté.
EWIs connexes ¶
Pas d’EWIs connexes.
Instruction de sélection¶
Snowflake prend en charge la syntaxe SELECT
de Teradata à quelques exceptions près. Tout d’abord, il ne prend pas en charge l’abréviation SEL
.
Teradata
SEL DISTINCT col1, col2 FROM table1
Snowflake
SELECT DISTINCT col1,
col2 FROM
table1;
Teradata prend en charge le référencement d’un alias avant qu’il ne soit déclaré, ce qui n’est pas le cas de Snowflake. La transformation pour ce scénario consiste à prendre la colonne référencée et à modifier l’alias du nom de la colonne à laquelle elle fait référence.
Teradata
SELECT
my_val, sum(col1),
col2 AS my_val FROM table1
Snowflake
SELECT
my_val,
sum(col1),
col2 AS my_val FROM
table1;
Options de clause supprimées¶
Les options de clause suivantes ne sont pas pertinentes pour Snowflake, elles sont donc supprimées lors de la migration.
Teradata |
Snowflake |
---|---|
Développer |
Aucune prise en charge |
Normaliser |
Aucune prise en charge |
Avec option de vérification (requête) |
Aucune prise en charge |
Problèmes connus¶
1. SEL abbreviation unsupported¶
L’abréviation n’est pas prise en charge dans Snowflake mais elle est traduite correctement en la remplaçant par SELECT.
EWIs connexes¶
Pas d’EWIs connexes.
Prédicat ANY¶
Avertissement
Il s’agit d’un travail en cours, des modifications pourront être apportées à l’avenir.
Description¶
Dans Teradata, permet la quantification dans une opération de comparaison ou un prédicat IN/NOT IN. La comparaison de l’expression et d’au moins une valeur de l’ensemble des valeurs retournées par la sous-requête est vraie. Pour plus d’informations, veuillez consulter la documentation Teradata suivante.
Syntaxe Teradata
{ expression quantifier ( literal [ {, | OR} ... ] ) |
{ expression | ( expression [,...] ) } quantifier ( subquery )
}
Où le quantificateur :
{ comparison_operator [ NOT ] IN } { ALL |ANY | SOME }
Syntaxe Snowflake
Sous la forme d’une sous-requête, IN est équivalent à = ANY
et NOT IN est équivalent à <> ALL
. Pour plus d’informations, consultez la documentation Snowflake suivante.
Pour comparer les valeurs individuelles :
<value> [ NOT ] IN ( <value_1> [ , <value_2> ... ] )
Pour comparer les constructeurs de lignes (listes de valeurs entre parenthèses) :
( <value_A> [, <value_B> ... ] ) [ NOT ] IN ( ( <value_1> [ , <value_2> ... ] ) [ , ( <value_3> [ , <value_4> ... ] ) ... ] )
Pour comparer une valeur aux valeurs renvoyées par une sous-requête :
<value> [ NOT ] IN ( <subquery> )
Sample Source Patterns
Données d’échantillon
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);
Prédicat Égal avec ANY dans la clause WHERE
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 |
Autres opérateurs de comparaison dans la clause WHERE
Lorsqu’il existe d’autres opérateurs de comparaison, la traduction équivalente consiste à ajouter une sous-requête avec la logique requise.
Teradata
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo < ANY(100,300,500) ;
Nom |
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);
NAME |
DEPTNO |
---|---|
Alice |
100 |
Eve |
100 |
Bob |
300 |
David |
200 |
IN ANY dans la clause WHERE
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 |
NOT IN ALL dans la clause WHERE
Teradata
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN ALL(100, 200);
Nom |
DeptNo |
---|---|
Charlie |
500 |
Bob |
300 |
Snowflake
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN (100, 200);
Nom |
DeptNo |
---|---|
Charlie |
500 |
Bob |
300 |
Known Issues
NOT IN ANY dans la clause WHERE
Teradata
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN ANY(100, 200);
Nom |
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);
Nom |
DeptNo |
---|---|
Eve |
100 |
Charlie |
500 |
Alice |
100 |
David |
200 |
Bob |
300 |
Related EWIs
Pas d’EWIs connexes.
Clause Expand On
Description
La clause Expand On développe une colonne dont le type de données est period, créant ainsi une série temporelle régulière de lignes basée sur la valeur de la période dans la ligne d’entrée. Pour plus d’informations sur la clause Expand On, consultez la documentation Teradata.
Sample Source Patterns
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Données d’échantillon¶
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 ***/!!!);
Clause Expand On¶
Supposons que vous souhaitiez étendre la colonne des périodes en secondes. Pour ce faire, la clause Expand On dispose d’une expansion de période d’ancrage et d’une expansion littérale d’intervalle.
Anchor Period Expansion
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 ne prend pas en charge la clause Expand On. Pour reproduire les mêmes résultats et fonctionnalités, le code Teradata SQL sera contenu dans un bloc CTE, avec une fonction EXPAND_ON_UDF et TABLE, en utilisant la fonction FLATTEN pour renvoyer plusieurs lignes, ROW_COUNT_UDF et DIFF_TTIME_PERIOD_UDF pour indiquer combien de lignes sont nécessaires et renvoyer VALUE pour aider EXPAND_ON_UDF à calculer les différentes séries temporelles régulières. Ce bloc CTE renvoie le même alias d’expansion des colonnes que dans la clause Expand On, de sorte que le résultat peut être utilisé dans n’importe quelle utilisation du type de données période.
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 |
Problèmes connus¶
La clause Expand On peut utiliser l’expansion littérale par intervalle, dans ce cas, SnowConvert ajoutera une erreur indiquant que cette traduction est planifiée.
Expansion littérale de l’intervalle¶
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 connexes¶
SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.
SSC-EWI-TD0053 : Snowflake ne prend pas en charge le type de données période, toutes les périodes sont gérées comme varchar à la place.
Normaliser¶
Description¶
NORMALIZE spécifie que les valeurs de période de la colonne de la première période qui se rencontrent ou se chevauchent sont combinées pour former une période qui englobe les valeurs de période individuelles. Pour plus d’informations sur la clause Normalize, consultez la documentation Teradata.
Modèles d’échantillons de sources¶
Note
Certaines parties du code de sortie sont omises pour des raisons de clarté.
Données d’échantillon¶
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 ***/!!!);
Clause Normalize¶
Supposons que vous souhaitiez utiliser la clause Normalize avec l’identifiant de l’employé.
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 |
Problèmes connus¶
La clause de normalisation peut utiliser ON MEETS OR OVERLAPS, ON OVERLAPS ou ON OVERLAPS OR MEETS, pour ces cas SnowConvert ajoutera une erreur indiquant que cette traduction est prévue pour l’avenir.
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 connexes¶
SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.
SSC-EWI-TD0079 : La colonne de type de période exigée n’a pas été trouvée.
SSC-EWI-TD0053 : Snowflake ne prend pas en charge le type de données période, toutes les périodes sont gérées comme varchar à la place.
Reset When¶
Description¶
Reset When détermine la partition sur laquelle une fonction de la fenêtre SQL opère en fonction d’une condition spécifique. Si la condition est évaluée à True, une nouvelle sous-partition dynamique est créée à l’intérieur de la partition de fenêtre existante. Pour plus d’informations sur Reset When, consultez la documentation Teradata .
Modèles d’échantillons de sources¶
Données d’échantillon¶
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 |
solde |
---|---|---|
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 |
solde |
---|---|---|
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¶
Pour chaque compte, supposons que vous souhaitiez analyser la séquence des augmentations mensuelles consécutives du solde. Lorsque le solde d’un mois est inférieur ou égal au solde du mois précédent, l’exigence est de remettre le compteur à zéro et de redémarrer.
Pour analyser ces données, Teradata SQL utilise une fonction de fenêtre avec un agrégat imbriqué et une instruction Reset When, comme suit :
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 ne prend pas en charge la clause Reset When dans les fonctions de fenêtre. Pour reproduire le même résultat, le code Teradata SQL doit être traduit en utilisant la syntaxe native de SQL et des sous-requêtes imbriquées, comme suit :
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 |
Deux sous-requêtes imbriquées sont nécessaires pour prendre en charge la fonctionnalité Reset When de Snowflake.
Dans la requête interne, un indicateur de partition dynamique (dynamic_part) est créé et alimenté. dynamic_part est défini sur 1 si le solde d’un mois est inférieur ou égal au solde du mois précédent ; dans le cas contraire, il est défini sur 0.
Dans la couche suivante, un attribut new_dynamic_part est généré en tant que résultat d’une fonction de fenêtre SUM.
Enfin, une new_dynamic_part est ajoutée en tant que nouvel attribut de partition (partition dynamique) à l’attribut de partition existant (account_id) et applique la même fonction de fenêtre ROW_NUMBER() que dans Teradata.
Après ces modifications, Snowflake génère la même sortie que Teradata.
Reset When lorsque la fonction conditionnelle de la fenêtre est une colonne¶
Même exemple que ci-dessus, sauf que la fonction de fenêtre utilisée dans la condition RESET WHEN est définie comme une colonne appelée previous
. Cette variation modifie légèrement la transformation puisqu’il n’est plus nécessaire de définir la valeur previous_value
comme dans l’exemple précédent. Il s’agit de la même solution.
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 |
Problèmes connus¶
La clause RESET WHEN peut présenter quelques variations, notamment en ce qui concerne son état. Actuellement, SnowConvert ne supporte que les conditions binaires (<=, >=, <> ou =), dans tout autre type, comme IS NOT NULL
, SnowConvert supprimera la clause RESET WHEN et ajoutera un message d’erreur puisqu’elle n’est pas prise en charge dans Snowflake, comme le montre l’exemple suivant.
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 connexes¶
SSC-EWI-TD0077 : la clause RESET WHEN n’est pas prise en charge dans ce scénario en raison de sa condition.
Clause SAMPLE¶
Description¶
La clause SAMPLE de Teradata réduit le nombre de lignes à traiter et renvoie un ou plusieurs échantillons de lignes sous la forme d’une liste de fractions ou d’une liste de nombres de lignes. La clause est utilisée dans la requête SELECT. Pour plus d’informations, veuillez consulter la documentation Teradata suivante.
Syntaxe Teradata
SAMPLE
[ WITH REPLACEMENT ]
[ RANDOMIZED LOCALIZATION ]
{ { fraction_description | count_description } [,...] |
when_clause ]
}
Syntaxe Snowflake
Pour plus d’informations, consultez la documentation Snowflake suivante. SAMPLE
et TABLESAMPLE
sont synonymes.
SELECT ...
FROM ...
{ SAMPLE | TABLESAMPLE } [ samplingMethod ]
[ ... ]
Où :
samplingMethod ::= {
{ BERNOULLI | ROW } ( { <probability> | <num> ROWS } ) |
{ SYSTEM | BLOCK } ( <probability> ) [ { REPEATABLE | SEED } ( <seed> ) ] }
Dans Snowflake, les mots-clés suivants peuvent être utilisés de manière interchangeable :
SAMPLE | TABLESAMPLE
BERNOULLI | ROW
SYSTEM | BLOCK
REPEATABLE | SEED
Examinez la table suivante pour vérifier les différences clés.
Comportement SAMPLE |
Teradata |
Snowflake |
---|---|---|
Échantillon par probabilité |
Également connu sous le nom de description de fraction. Il doit s’agir d’un nombre fractionnaire compris entre 0,1 et 1. |
Nombre décimal compris entre 0 et 100. |
Nombre fixe de lignes |
Également connu sous le nom de description de comptage. Il s’agit d’un entier positif qui détermine le nombre de lignes à échantillonner. |
Il indique le nombre de lignes (jusqu’à 1 000 000) à échantillonner dans la table. Peut être un entier compris entre |
Lignes répétées |
Connu sous le nom de |
Connu sous le nom de |
Méthodes d’échantillonnage |
Proportional et |
|
Modèles d’échantillons de sources¶
Données d’échantillon¶
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);
Clause SAMPLE¶
Nombre fixe de lignes
Remarquez que pour cet exemple, le nombre de lignes est un nombre fixe, mais que le résultat n’est pas nécessairement le même à chaque exécution.
Teradata
SELECT * FROM Employee SAMPLE 2;
2 lignes.
Snowflake
SELECT * FROM Employee SAMPLE (2 ROWS);
2 lignes.
Nombre de lignes basé sur la probabilité
Cette option renvoie diverses lignes en fonction de l’ensemble des probabilités.
Teradata
SELECT * FROM Employee SAMPLE 0.25;
25 % de la probabilité pour chaque ligne : 1 ligne de sortie.
Snowflake
SELECT * FROM Employee SAMPLE (25);
25 % de la probabilité pour chaque ligne : 1 ligne de sortie.
Problèmes connus¶
Nombre fixe de lignes avec remplacement¶
Cette option renvoie un nombre fixe de lignes et permet la répétition des lignes. Dans Snowflake, il n’est pas possible de requérir plus d’échantillons que de lignes dans une table.
Échantillon Teradata
SELECT * FROM Employee SAMPLE WITH REPLACEMENT 8;
EmpNo |
Nom |
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 |