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 clauseUSINGpour 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
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

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é.

Voir Opérateurs d’ensemble

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;
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

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

  1. 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';
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 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;
Copy

Snowflake

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

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é.

Voir Instruction d’insertion

Dans Teradata, il existe une autre syntaxeINSERTqui 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'));
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

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;
Copy
INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
Copy
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;
Copy
 INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
Copy
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;
Copy
 INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
Copy
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;
Copy
 INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
Copy

Problèmes connus

Aucun problème n’a été constaté.

EWIs connexes

Pas d’EWIs connexes.

Instruction de sélection

Voir 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
Copy

Snowflake

 SELECT DISTINCT col1,
col2 FROM
table1;
Copy

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
Copy

Snowflake

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

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 )
}
Copy

Où le quantificateur :

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

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> ...  ] )
Copy

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> ... ] )  ...  ]  )
Copy

Pour comparer une valeur aux valeurs renvoyées par une sous-requête :

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

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);
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
Prédicat Égal avec ANY dans la clause WHERE

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

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) ;
Copy

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);
Copy

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) ;
Copy

DeptNo

100

500

100

300

Snowflake

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

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);
Copy

Nom

DeptNo

Charlie

500

Bob

300

Snowflake

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

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);
Copy

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);
Copy

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'
        )
    );
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
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;
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 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;
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

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;
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 connexes

  1. SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.

  2. 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')
    );
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
Clause Normalize

Supposons que vous souhaitiez utiliser la clause Normalize avec l’identifiant de l’employé.

 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

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;
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 connexes

  1. SSC-EWI-0073 : En attente de l’examen de l’équivalence fonctionnelle.

  2. SSC-EWI-TD0079 : La colonne de type de période exigée n’a pas été trouvée.

  3. 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);
Copy

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);
Copy

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;
Copy
account_idmonth_idbalancebalance_increase
11600
12991
13940
14900
15800
16881
17902
18923
19100
110601
111802
112100

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;
Copy
account_idmonth_idbalancebalance_increase
11600
12991
13940
14900
15800
16881
17902
18923
19100
110601
111802
112100

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;
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

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;
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 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 ]
  }
Copy

Syntaxe Snowflake

Pour plus d’informations, consultez la documentation Snowflake suivante. SAMPLE et TABLESAMPLE sont synonymes.

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

Où :

 samplingMethod ::= { 
{ BERNOULLI | ROW } ( { <probability> | <num> ROWS } ) |
{ SYSTEM | BLOCK } ( <probability> ) [ { REPEATABLE | SEED } ( <seed> ) ] }
Copy
  • 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 0 (aucune ligne sélectionnée) et 1000000 inclus.

Lignes répétées

Connu sous le nom de WITH REPLACEMENT. Permet d’interroger plus d’échantillons qu’il n’y a de lignes dans la table.

Connu sous le nom de REPEATABLE ou SEED. Utilisé pour rendre la requête déterministe. Cela signifie que le même ensemble de lignes sera identique à chaque exécution de la requête.

Méthodes d’échantillonnage

Proportional et RANDOMIZED ALLOCATION.

BERNOULLI ou SYSTEM.

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);
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
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;
Copy

2 lignes.

Snowflake

 SELECT * FROM Employee SAMPLE (2 ROWS);
Copy

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;
Copy

25 % de la probabilité pour chaque ligne : 1 ligne de sortie.

Snowflake

 SELECT * FROM Employee SAMPLE (25);
Copy

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;
Copy

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