SnowConvert : Teradata

Opérations sur les données numériques

Précision des calculs

Teradata et Snowflake traitent les calculs différemment :

  • Teradata arrondit les données après chaque étape de calcul en fonction du type de données :

    • Pour les types décimaux, il conserve la plus grande précision

    • Pour les types NUMBER, il conserve toute sa précision

  • Snowflake stocke toutes les données en utilisant le type de données NUMBER, ce qui permet de maintenir une précision totale tout au long des calculs. Cela peut conduire à des résultats différents de ceux de Teradata, en particulier lorsque vous travaillez avec des types décimaux, entiers ou flottants.

Cette différence de comportement n’est pas corrigée lors de la conversion du code, car ce n’est généralement pas ce que les développeurs ont l’intention de modifier.

Teradata : SELECT (1,00/28) * 15,00 /* donne 0,60 */

Snowflake arrondira le résultat de la division (1,00/28) * 15,00 à deux décimales : SELECT (1,00/28) * 15,00 = 0,535710 = 0,54

Division entier-entier

Lors de la division de deux valeurs entières, Teradata effectue une troncation (floor), tandis que Snowflake effectue un arrondi. Pour maintenir un comportement cohérent pendant la migration, la conversion automatisée du code ajoute automatiquement une instruction TRUNC dans ces cas.

Teradata : SELECT (5/3) = 1 /donne 1 puisque la division entière arrondit à l’inférieur/

Snowflake : en divisant 5 par 3, on obtient 1,6666666, qui s’arrondit à 2

Division tronquée dans Snowflake : SELECT TRUNC(5/3) donne 1

Arrondi bancaire

Teradata propose l’arrondi bancaire via le paramètre ROUNDHALFWAYMAGUP, tandis que Snowflake utilise uniquement des méthodes d’arrondi standard.

SQL

Teradata

Snowflake

CAST(1.05 AS DECIMAL(9,1))

<mark style= »background-color:orange; »>1.0

1.1

CAST(1.15 AS DECIMAL(9,1))

1,2

1,2

CAST(1.25 AS DECIMAL(9,1))

1.2

1.3

CAST(1.35 AS DECIMAL(9,1))

1,4

1,4

CAST(1.45 AS DECIMAL(9,1))

1.4

1.5

CAST(1.55 AS DECIMAL(9,1))

1,6

1,6

CAST( 1.65 AS DECIMAL(9,1))

1.6

1.7

CAST(1.75 AS DECIMAL(9,1))

1,8

1,8

CAST(1.85 AS DECIMAL(9,1))

1.8

1.9

CAST(1.95 AS DECIMAL(9,1))

2,0

2,0

Conversion de décimaux en entiers

Teradata et Snowflake traitent différemment les valeurs décimales. Alors que Teradata tronque les valeurs décimales, Snowflake les arrondit à l’entier le plus proche. Pour maintenir la cohérence avec le comportement de Teradata, le processus de conversion ajoute automatiquement une instruction TRUNC.

SQL

Teradata

Snowflake

CAST(<mark style= »background-color:blue;>1.0 AS INTEGER)

1

1

CAST(1.1 AS INTEGER)

1

1

CAST(1.2 AS INTEGER)

1

1

CAST( 1.3 AS INTEGER)

1

1

CAST(1.4 AS INTEGER)

1

1

CAST(1.5 AS INTEGER)

1

2

CAST(1.6 AS INTEGER)

1

2

CAST(1.7 AS INTEGER)

1

2

CAST(1.8 AS INTEGER)

1

2

CAST(1.9 AS INTEGER)

1

2

Nombre sans précision/échelle

Lorsqu’une colonne Teradata NUMBER est définie sans spécifier d’échelle ou de précision, elle peut stocker des valeurs décimales avec une échelle variable (de 0 à 38), tant que la précision totale reste inférieure à 38 chiffres. Cependant, Snowflake exige des valeurs d’échelle et de précision fixes pour les colonnes NUMBER. Voici un exemple de la façon dont les nombres sont définis dans une table Teradata avec ce format flexible :

CREATE MULTISET TABLE DATABASEXYZ.TABLE_NUMS
     (NUM_COL1 NUMBER(*),
      NUM_COL2 NUMBER,
      NUM_COL3 NUMBER(38,*));
Copy

La table suivante montre deux exemples de valeurs qui dépassent les limites de taille de colonne de Snowflake. Ces valeurs peuvent apparaître dans n’importe quelle colonne de Teradata présentée précédemment.

Valeur 1 : 123 345 678 901 234 567 891 012,0123456789

Valeur 2 : 123,12345678901234567890

Ces valeurs numériques nécessiteraient un type de données NUMBER(42, 20), ce qui dépasse la limite de précision maximale de 38 fixée par Snowflake. Snowflake travaille actuellement à la mise en place d’une fonctionnalité de précision et d’échelle flexible.

Troncation sur INSERT pour les instructions SQL DML

Teradata tronque automatiquement les valeurs de chaîne qui dépassent la longueur de champ définie lors de l’insertion. Alors que SnowConvert conserve la même longueur de champ pendant la conversion (par exemple, VARCHAR(20) reste VARCHAR(20)), Snowflake ne tronque pas automatiquement les chaînes trop grandes. Si votre processus d’ingestion des données dépend de la troncation automatique, vous devrez le modifier manuellement en ajoutant une fonction LEFT(). SnowConvert n’ajoute pas intentionnellement la troncation automatiquement en raison de l’impact potentiel sur l’ensemble de la base de code.

Exemple d’émission par défaut d’un flottant :

/* <sc-table> TABLE DUMMY.EXAMPLE </sc-table> */
/**** WARNING: SET TABLE FUNCTIONALITY NOT SUPPORTED ****/
CREATE TABLE DUMMY.PUBLIC.EXAMPLE (
LOGTYPE INTEGER,
OPERSEQ INTEGER DEFAULT 0,
RUNTIME FLOAT /**** ERROR: DEFAULT CURRENT_TIME NOT VALID FOR DATA TYPE ****/
);
Copy

Agrégation de données flottantes

Les nombres à virgule flottante sont des représentations approximatives des valeurs décimales. En raison de ces approximations, différents systèmes de base de données peuvent produire des résultats légèrement différents lorsqu’ils effectuent des calculs et des agrégations avec des types de données flottantes. Cette variation est due au fait que chaque système de base de données gère l’arithmétique à virgule flottante et l’arrondi à sa manière.

Autres considérations

Élimination des jointures

Snowflake exécute les requêtes SQL exactement comme elles sont écrites, y compris toutes les jointures spécifiées, qu’elles affectent ou non les résultats finaux. Contrairement à Snowflake, Teradata peut supprimer automatiquement les jointures inutiles en utilisant les relations de clés primaires et étrangères définies dans la structure des tables. Cette fonction de Teradata permet principalement d’éviter les requêtes mal écrites et ne pose généralement de problème que lorsque le code a été spécifiquement écrit pour utiliser cette fonction. Si votre code existant a été conçu pour tirer parti de la fonction d’élimination des jointures de Teradata, les outils de conversion de code automatisés ne peuvent pas remédier à cette limite. Dans de tels cas, il se peut que vous deviez revoir certaines parties de votre solution.

Utilisation des fonctions de fenêtre avec max() et order by

Comportement et valeurs par défaut de Teradata :

Par défaut : lorsqu’une clause ORDER BY est présente mais qu’aucune clause ROWS ou ROWS BETWEEN n’est spécifiée, les fonctions d’agrégation de la fenêtre Teradata SQL utilisent automatiquement ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING.

Comportement de Snowflake et valeurs par défaut :

Par défaut : lorsque vous utilisez une fonction d’agrégation de fenêtres avec une clause ORDER BY mais sans spécifier ROWS ou ROWS BETWEEN, Snowflake applique automatiquement ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW comme cadre de fenêtre.

Exemple :

Vous trouverez ci-dessous un exemple de table nommée TEST_WIN qui présente les données salariales des employés de différents services.

DEPT_NMDEPT_NOEMP_NOSALARY
SALES10115000
SALES10126000
HR20211000
HR20222000
PS30317000
PS30329000

Le code suivant, lorsqu’il est exécuté dans Teradata, calcule le salaire le plus élevé parmi tous les employés, regroupés par département.

SELECT DEPT_NM, SALARY ,DEPT_NO,
MAX(SALARY) OVER ( ORDER BY DEPT_NO  ) AS MAX_DEPT_SALARY
FROM TEST_WIN;
Copy
DEPT_NMSALARYDEPT_NOMAX_DEPT_SALARY
SALES6000109000
SALES5000109000
HR2000209000
HR1000209000
PS7000309000
PS9000309000

Lorsque vous exécutez le code converti à l’aide de Snowflake-SnowConvert, il se peut que vous constatiez des résultats différents (valeurs mises en évidence). Ces différences sont attendues et correspondent aux paramètres par défaut de Snowflake.

SELECT DEPT_NM, SALARY ,DEPT_NO,
MAX(SALARY) OVER ( ORDER BY DEPT_NO  ) AS MAX_DEPT_SALARY
FROM TEST_WIN;
Copy
DEPT_NMSALARYDEPT_NOMAX_DEPT_SALARY
SALES5000106000
SALES6000106000
HR1000206000
HR2000206000
PS7000309000
PS9000309000

Pour obtenir des résultats identiques à ceux de Teradata, vous devez spécifier la valeur ROWS/RANGE comme indiqué dans le code ci-dessous.

SELECT DEPT_NM, SALARY ,DEPT_NO,
MAX(SALARY) OVER ( ORDER BY DEPT_NO RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS MAX_DEPT_SALARY
FROM TEST WIN;
Copy
DEPT_NMSALARYDEPT_NOMAX_DEPT_SALARY
SALES5000109000
SALES6000109000
HR1000209000
HR2000209000
PS7000309000
PS9000309000

La clause RANGE/ROWS définit explicitement l’ordre des lignes. Vous pouvez obtenir des résultats similaires en supprimant complètement la clause ORDER BY.

Références

Snowflake : https://docs.snowflake.com/en/sql-reference/functions-analytic.html Teradata : https://docs.teradata.com/r/756LNiPSFdY~4JcCCcR5Cw/dIV_fAtkK3UeUIQ5_uucQw