SnowConvert: Teradata

Operationen mit numerischen Daten

Genauigkeit der Berechnung

Teradata und Snowflake behandeln Berechnungen unterschiedlich:

  • Teradata rundet Zahlen nach jedem Berechnungsschritt auf der Grundlage des Datentyps:

    • Bei Dezimaltypen wird die größere Genauigkeit beibehalten.

    • Für NUMBER wird die vollständige Genauigkeit beibehalten.

  • Snowflake speichert alle Zahlen unter Verwendung des Datentyps NUMBER, sodass die volle Genauigkeit bei allen Berechnungen erhalten bleibt. Dies kann zu unterschiedlichen Ergebnissen im Vergleich zu Teradata führen, insbesondere wenn Sie mit Dezimalzahl-, Ganzzahl- oder Gleitkommatypen arbeiten.

Dieser Unterschied im Verhalten wird bei der Konvertierung des Codes nicht angepasst, da die Entwickler dies in der Regel nicht zu ändern beabsichtigen.

Teradata: SELECT (1.00/28) * 15.00 /* gibt 0.60 zurück */

Snowflake rundet das Ergebnis der Division (1.00/28) * 15.00 auf zwei Dezimalstellen: SELECT (1.00/28) * 15.00 = 0.535710 = 0.54

Ganzzahl-Ganzzahl-Division

Bei der Division von zwei ganzzahligen Werten führt Teradata eine Kürzung (niedrigere Ganzzahl) durch, während Snowflake eine Rundung vornimmt. Um ein konsistentes Verhalten während der Migration zu gewährleisten, fügt die automatische Codekonvertierung in diesen Fällen automatisch eine TRUNC-Anweisung hinzu.

Teradata: SELECT (5/3) = 1 /* Gibt 1 zurück, da Ganzzahldivision abrundet */

Snowflake: Wenn Sie 5 durch 3 teilen, ist das Ergebnis 1,6666666, was auf 2 gerundet wird

Gekürzte Division in Snowflake: SELECT TRUNC(5/3) gibt 1 zurück

Kaufmännisches Runden

Teradata bietet kaufmännisches Runden über den Parameter ROUNDHALFWAYMAGUP, während Snowflake nur Standard-Rundungsmethoden verwendet.

SQL

Teradata

Snowflake

CAST( 1.05 AS DECIMAL(9,1))

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

Konvertierung von Dezimalzahl in Ganzzahl

Teradata und Snowflake behandeln Dezimalwerte unterschiedlich. Während Teradata Dezimalwerte kürzt, rundet Snowflake sie auf die nächste Ganzzahl. Um die Konsistenz mit dem Verhalten von Teradata zu wahren, fügt der Konvertierungsprozess automatisch eine TRUNC-Anweisung hinzu.

SQL

Teradata

Snowflake

CAST( 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

Zahl ohne Genauigkeit/Dezimalstellenzahl

Wenn eine Teradata-NUMBER-Spalte ohne Angabe von Dezimalstellenzahl oder Genauigkeit definiert wird, kann sie Dezimalwerte mit unterschiedlicher Dezimalstellenanzahl (von 0 bis 38) speichern, solange die Gesamtgenauigkeit innerhalb von 38 Stellen bleibt. Snowflake erfordert jedoch feste Dezimalstellenanzahl- und Genauigkeitswerte für NUMBER-Spalten. Hier sehen Sie ein Beispiel dafür, wie Zahlen in einer Teradata-Tabelle mit diesem flexiblen Format definiert werden:

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

Die folgende Tabelle zeigt zwei Beispiele für Werte, die die Spaltengrößenbeschränkungen von Snowflake überschreiten. Diese Werte können in jeder der zuvor angezeigten Teradata-Spalten erscheinen.

Wert 1: 123,345,678,901,234,567,891,012.0123456789

Wert 2: 123.12345678901234567890

Diese numerischen Werte würden einen NUMBER(42, 20)-Datentyp erfordern, der die maximale Snowflake-Genauigkeitsbeschränkung von 38 Stellen überschreitet. Snowflake arbeitet derzeit an der Implementierung einer flexiblen Funktionalität für Dezimalstellenanzahl und Genauigkeit.

Kürzen bei INSERT für SQL-DML-Anweisungen

Teradata schneidet Zeichenfolgenwerte, die die definierte Feldlänge überschreiten, beim Einfügen automatisch ab. Während SnowConvert bei der Konvertierung die gleichen Feldlängen beibehält (z. B. bleibt VARCHAR(20) unverändert VARCHAR(20)), schneidet Snowflake übergroße Zeichenfolgen nicht automatisch ab. Wenn Ihr Datenerfassungsprozess automatisches Kürzen erfordert, müssen Sie ihn manuell ändern, indem Sie eine LEFT()-Funktion hinzufügen. SnowConvert fügt Kürzen absichtlich nicht automatisch hinzu, da dies Auswirkungen auf die gesamte Codebasis haben könnte.

Beispiel für Problem bei Gleitkomma-Standardwert

/* <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

Aggregation von Gleitkommadaten

Gleitkommazahlen sind ungefähre Darstellungen von Dezimalwerten. Aufgrund dieser Näherungen können verschiedene Datenbanksysteme bei der Durchführung von Berechnungen und Aggregationen mit Gleitkomma-Datentypen leicht unterschiedliche Ergebnisse liefern. Diese Abweichung ist darauf zurückzuführen, dass jedes Datenbanksystem Gleitkommaarithmetik und Rundung auf seine eigene Weise handhabt.

Weitere Überlegungen

Beseitigen von Join

Snowflake führt SQL-Abfragen genau so aus, wie sie geschrieben wurden, einschließlich aller angegebenen Joins, unabhängig davon, ob sie die Endergebnisse beeinflussen. Im Gegensatz zu Snowflake kann Teradata automatisch unnötige Joins entfernen, indem es in der Tabellenstruktur definierte Primär- und Fremdschlüsselbeziehungen verwendet. Dieses Feature in Teradata hilft in erster Linie dabei, schlecht geschriebene Abfragen zu verhindern, und ist in der Regel nur dann ein Problem, wenn der Code speziell für die Nutzung dieser Funktion geschrieben wurde. Wenn Ihr vorhandener Code so konzipiert wurde, dass er die Vorteile des Features zur Eliminierung von Joins von Teradata nutzt, können automatische Codekonvertierungstools diese Beschränkung nicht umsetzen. In solchen Fällen müssen Sie möglicherweise Teile Ihrer Lösung umgestalten.

Verwendung von Fensterfunktionen mit max() und ORDER BY

Teradata-Verhalten und -Standardeinstellungen:

Standard: Wenn eine ORDER BY-Klausel vorhanden ist, aber keine ROWS- oder ROWS BETWEEN-Klausel angegeben ist, verwenden die Teradata-SQL Fensteraggregatfunktionen automatisch ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING.

Snowflake-Verhalten und Standardeinstellungen:

Standard: Wenn Sie eine Fensteraggregatfunktion mit einer ORDER BY-Klausel, aber ohne Angabe von ROWS oder ROWS BETWEEN verwenden, wendet Snowflake automatisch ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW als Fensterrahmen an.

Beispiel:

Unten sehen Sie eine Beispieltabelle mit dem Namen TEST_WIN, die Gehaltsdaten von Mitarbeitern in verschiedenen Abteilungen enthält.

DEPT_NMDEPT_NOEMP_NOSALARY
SALES10115000
SALES10126000
HR20211000
HR20222000
PS30317000
PS30329000

Der folgende Code, der in Teradata ausgeführt wird, berechnet das höchste Gehalt aller Mitarbeiter, gruppiert nach Abteilung.

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

Wenn Sie den konvertierten Code mit Snowflake-SnowConvert ausführen, werden Sie möglicherweise andere Ergebnisse (hervorgehobene Werte) feststellen. Diese Unterschiede sind zu erwarten und stimmen mit den Standardeinstellungen von Snowflake überein.

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

Um die gleichen Ergebnisse wie in Teradata zu erzielen, müssen Sie den Wert ROWS/RANGE angeben, wie im folgenden Code gezeigt.

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

Die RANGE/ROWS-Klausel definiert explizit, wie die Zeilen geordnet werden. Sie können ähnliche Ergebnisse erzielen, wenn Sie die ORDER BY-Klausel vollständig entfernen.

Referenzen

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