SnowConvert AI – Teradata – DML¶
Nesta seção, você encontrará a documentação para a referência de tradução de Elementos de linguagem de manipulação de dados.
Excluir instrução¶
Consulte Excluir instrução
O Teradata suporta a chamada de mais de uma tabela na cláusulaFROM, mas o Snowflake não. Portanto, é necessário usar a cláusulaUSINGpara fazer referência às tabelas extras envolvidas na condição.
Teradata
Delete
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
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;
Problemas conhecidos¶
1. DEL abbreviation unsupported¶
A abreviação não é compatível com o Snowflake, mas é convertida corretamente ao ser alterada para DELETE.
Operadores de conjuntos¶
Os operadores de conjunto SQL manipulam os conjuntos de resultados de várias consultas combinando os resultados de cada consulta em um único conjunto de resultados.
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Consulte Operadores de conjuntos
Os operadores de conjuntos no Teradata e no Snowflake têm a mesma sintaxe e cenários suportados EXCEPT, INTERSECT e UNION, exceto pela cláusula ALL no INTERSECT ALL, que não é suportada no Snowflake, resultando na parte do ALL como um código comentado após a conversão.
Teradata
Intersect¶
SELECT LastName, FirstName FROM employees
INTERSECT
SELECT FirstName, LastName FROM contractors;
SELECT LastName, FirstName FROM employees
INTERSECT ALL
SELECT FirstName, LastName FROM contractors;
Snowflake
Intersect¶
SELECT
LastName,
FirstName FROM
employees
INTERSECT
SELECT
FirstName,
LastName FROM
contractors;
SELECT
LastName,
FirstName FROM
employees
INTERSECT
!!!RESOLVE EWI!!! /*** SSC-EWI-0040 - THE 'INTERSECT ALL QUANTIFIER' CLAUSE IS NOT SUPPORTED IN SNOWFLAKE ***/!!! ALL
SELECT
FirstName,
LastName FROM
contractors;
Problemas conhecidos¶
1. INTERSECT ALL unsupported¶
INTERSECT ALL não é compatível com o Snowflake e a parte ALL será comentada.
EWIs relacionados¶
SSC-EWI-0040: Instrução incompatível.
Instrução de atualização¶
Descrição¶
Modifica os valores das colunas nas linhas existentes de uma tabela. (Referência de linguagem do Teradata SQL UPDATE)
Amostra de padrões da origem¶
Caso básico¶
Teradata
Update
UPDATE CRASHDUMPS.TABLE1 i
SET COLUMN4 = CRASHDUMPS.TABLE2.COLUMN3
WHERE i.COLUMN1 = CRASHDUMPS.TABLE2.COLUMN1
AND i.COLUMN3 = 'L';
Snowflake
Update
UPDATE CRASHDUMPS.TABLE1 AS i
SET
i.COLUMN4 = CRASHDUMPS.TABLE2.COLUMN3
FROM
CRASHDUMPS.TABLE2
WHERE i.COLUMN1 = CRASHDUMPS.TABLE2.COLUMN1
AND UPPER(RTRIM( i.COLUMN3)) = UPPER(RTRIM('L'));
UPDATE com alias de encaminhamento¶
O Teradata suporta a referência a um alias antes que ele seja declarado, mas o Snowflake não. A transformação para esse cenário é pegar a tabela referenciada e alterar o alias do nome da tabela que ela referencia.
Teradata
Update
UPDATE i
FROM CRASHDUMPS.TABLE2, CRASHDUMPS.TABLE1 i
SET COLUMN4 = CRASHDUMPS.TABLE2.COLUMN3
WHERE i.COLUMN1 = CRASHDUMPS.TABLE2.COLUMN1
AND i.COLUMN3 = 'L';
Snowflake
Update
UPDATE CRASHDUMPS.TABLE1 AS i
SET
i.COLUMN4 = CRASHDUMPS.TABLE2.COLUMN3
FROM
CRASHDUMPS.TABLE2
WHERE i.COLUMN1 = CRASHDUMPS.TABLE2.COLUMN1
AND UPPER(RTRIM( i.COLUMN3)) = UPPER(RTRIM('L'));
UPDATE com tabela de destino na cláusula FROM¶
O Teradata oferece suporte para que a tabela de destino seja definida na cláusula FROM. Esta é removida no Snowflake para evitar alias duplicado e erros de referência de coluna ambígua.
Teradata
Update
UPDATE some_table
FROM some_table
SET Code = Code + 100
WHERE Name = 'A';
Snowflake
Update
UPDATE some_table
SET Code = Code + 100
WHERE
UPPER(RTRIM( Name)) = UPPER(RTRIM('A'));
EWIs relacionados¶
Sem EWIs relacionados.
Com modificador¶
Selecione a instrução que usa o modificador WITH com uma lista de várias consultas nomeadas também conhecidas como expressões de tabela comuns (CTEs).
Consulte Com modificador
O Snowflake suporta o modificador WITH do Teradata em uma instrução SELECT que tem vários CTEs (Common Table Expressions). O Teradata aceita qualquer ordem de definição do CTE, independentemente de ele ser referenciado antes de ser declarado ou não, mas o Snowflake exige que, se um CTE chamar outro CTE, ele deverá ser definido antes de ser chamado. Em seguida, a sequência convertida de CTEs dentro do WITH será reordenada no CTEs não referenciado, depois no CTE que chama o próximo CTE e assim por diante.
Quando houver um ciclo detectado na sequência de chamada WITH, ela será deixada como o original, sem nenhuma alteração na sequência, conforme detalhado em um exemplo de SSC-EWI-TD0077.
No exemplo abaixo, há dois CTEs nomeados como n1 e n2. O n1 refere-se a n2. Então o n2 deve ser definido primeiro no Snowflake como o código convertido correspondente.
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Teradata
Com modificador¶
WITH recursive n1(c1) as (select c1, c3 from t2, n1),
n2(c2) as (select c2 from tablex)
SELECT * FROM t1;
Snowflake
Com modificador¶
WITH RECURSIVE n1(c1) AS
(
SELECT
c1,
c3 from
t2, n1
),
n2(c2) AS
(
SELECT
c2 from
tablex
)
SELECT
* FROM
t1;
Problemas conhecidos¶
1. Impossible to reorder when cycles were found¶
Quando as referências de CTEs forem analisadas e houver um ciclo entre as chamadas de CTEs, os CTEs não serão solicitados.
EWIs relacionados¶
Sem EWIs relacionados.
Instrução Insert¶
Instrução SQL que adiciona novas linhas a uma tabela.
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Consulte Instrução Insert
No Teradata, há uma sintaxe alternativa de INSERTque atribui o valor de cada coluna da tabela em linha. Essa estrutura alternativa requer uma transformação especial para ser suportada no Snowflake. A atribuição em linha dos valores é separada e colocada dentro da parte VALUES(...) da instrução Snowflake INSERT INTO.
Teradata
Insert¶
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¶
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))));
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs Relacionados ¶
Sem EWIs relacionados.
LOGGING ERRORS¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Nota
Instrução não relevante.
Aviso
Observe que esta instrução é removida da de migração por se tratar de sintaxe não relevante. Isso significa que não é necessária no Snowflake.
Descrição¶
Instrução para registrar erros ao usar instruções como INSERT. ..SELECT. Consulte a documentação a seguir.
Amostra de padrões da origem¶
LOGGING ERRORS¶
Neste exemplo, observe que LOGGING ERRORS foi removido porque não é uma sintaxe relevante. A sintaxe não é necessária no Snowflake.
Teradata¶
INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ERRORS;
Snowflake¶
INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
LOGGING ALL ERRORS¶
Neste exemplo, observe que LOGGING ALL ERRORS foi removido porque não é uma sintaxe relevante. A sintaxe não é necessária no Snowflake.
Teradata¶
INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ALL ERRORS;
Snowflake¶
INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
LOGGING ERRORS WITH NO LIMIT¶
Neste exemplo, observe que LOGGING ERRORS WITH NO LIMIT foi removido porque não é uma sintaxe relevante. A sintaxe não é necessária no Snowflake.
Teradata¶
INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ERRORS WITH NO LIMIT;
Snowflake¶
INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
LOGGING ERRORS WITH LIMIT OF¶
Neste exemplo, observe que LOGGING ERRORS WITH LIMIT OF foi removido porque não é uma sintaxe relevante. A sintaxe não é necessária no Snowflake.
Teradata¶
INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ERRORS WITH LIMIT OF 100;
Snowflake¶
INSERT INTO MY_TABLE SELECT
*
FROM
MY_SAMPLE;
Problemas conhecidos ¶
Não foram encontrados problemas.
EWIs Relacionados ¶
Sem EWIs relacionados.
Instrução Select¶
Consulte Instrução Select
O Snowflake é compatível com a sintaxe SELECT do Teradata, com algumas exceções. Principalmente, ele não suporta a abreviação SEL.
Teradata
Sel
SEL DISTINCT col1, col2 FROM table1
Snowflake
Select
SELECT DISTINCT col1,
col2 FROM
table1;
O Teradata suporta a referência a um alias antes que ele seja declarado, mas o Snowflake não. A transformação para esse cenário é pegar a coluna referenciada e alterar o alias do nome da coluna a que ela faz referência.
Teradata
Alias
SELECT
my_val, sum(col1),
col2 AS my_val FROM table1
Snowflake
Alias
SELECT
my_val,
SUM(col1),
col2 AS my_val FROM
table1;
Opções de cláusula removidas¶
As opções de cláusula a seguir não são relevantes para o Snowflake e, portanto, são removidas durante a migração.
Teradata |
Snowflake |
|---|---|
Expand on |
Sem suporte |
Normalize |
Sem suporte |
Com opção de verificação (Query) |
Sem suporte |
Problemas conhecidos¶
1. SEL abbreviation unsupported¶
A abreviação não é compatível com o Snowflake, mas é convertida corretamente ao ser alterada para SELECT.
EWIs relacionados¶
Sem EWIs relacionados.
Predicado ANY¶
Aviso
Este é um trabalho em andamento, alterações podem ser aplicadas no futuro.
Descrição¶
No Teradata, permite a quantificação em uma operação de comparação ou no predicado IN/NOT IN. A comparação da expressão com pelo menos um valor no conjunto de valores retornados pela subconsulta é verdadeira. Para obter mais informações, consulte a seguinte documentação do Teradata.
Sintaxe do Teradata
{ expression quantifier ( literal [ {, | OR} ... ] ) |
{ expression | ( expression [,...] ) } quantifier ( subquery )
}
Onde o quantificador:
{ comparison_operator [ NOT ] IN } { ALL |ANY | SOME }
Sintaxe do Snowflake
SuccessPlaceholder
Na forma de subconsulta, IN é equivalente a = ANY e NOT IN é equivalente a <> ALL. Consulte a documentação do Snowflake a seguir para obter mais informações.
Para comparar valores individuais:
<value> [ NOT ] IN ( <value_1> [ , <value_2> ... ] )
Para comparar row constructors (listas de valores entre parênteses):
( <value_A> [, <value_B> ... ] ) [ NOT ] IN ( ( <value_1> [ , <value_2> ... ] ) [ , ( <value_3> [ , <value_4> ... ] ) ... ] )
Para comparar um valor com os valores retornados por uma subconsulta:
<value> [ NOT ] IN ( <subquery> )
Amostra de padrões da origem¶
Amostra de dados¶
Teradata¶
Consulta¶
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¶
Consulta¶
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);
Igual a ANY em cláusula WHERE;¶
Teradata
Entrada¶
SELECT DeptNo
FROM Employee
WHERE DeptNo = ANY(100,300,500) ;
Saída¶
DeptNo |
|---|
100 |
500 |
100 |
300 |
Snowflake
Entrada¶
SELECT DeptNo
FROM Employee
WHERE DeptNo IN(100,300,500) ;
Saída¶
DeptNo |
|---|
100 |
500 |
100 |
300 |
Outros operadores de comparação na cláusula WHERE¶
Quando há outros operadores de comparação, a conversão equivalente é adicionar uma subconsulta com a lógica necessária.
Teradata
Entrada¶
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo < ANY(100,300,500) ;
Saída¶
Nome |
DeptNo |
|---|---|
Eve |
100 |
Alice |
100 |
David |
200 |
Bob |
300 |
Snowflake
Entrada¶
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo < ANY
(SELECT DeptNo
FROM Employee
WHERE DeptNo > 100
OR DeptNo > 300
OR DeptNo > 500);
Saída¶
NAME |
DEPTNO |
|---|---|
Alice |
100 |
Eve |
100 |
Bob |
300 |
David |
200 |
IN ANY na cláusula WHERE¶
Teradata
Entrada¶
SELECT DeptNo
FROM Employee
WHERE DeptNo IN ANY(100,300,500) ;
Saída¶
DeptNo |
|---|
100 |
500 |
100 |
300 |
Snowflake
Entrada¶
SELECT DeptNo
FROM Employee
WHERE DeptNo IN(100,300,500) ;
Saída¶
DeptNo |
|---|
100 |
500 |
100 |
300 |
NOT IN ALL na cláusula WHERE¶
Teradata
Entrada¶
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN ALL(100, 200);
Saída¶
Nome |
DeptNo |
|---|---|
Charlie |
500 |
Bob |
300 |
Snowflake
Entrada¶
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN (100, 200);
Saída¶
Nome |
DeptNo |
|---|---|
Charlie |
500 |
Bob |
300 |
Problemas conhecidos¶
NOT IN ANY na cláusula WHERE¶
Teradata
Entrada¶
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN ANY(100, 200);
Saída¶
Nome |
DeptNo |
|---|---|
Eve |
100 |
Charlie |
500 |
Alice |
100 |
David |
200 |
Bob |
300 |
Snowflake
Entrada¶
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo IN (100, 200)
OR DeptNo NOT IN (100, 200);
Saída¶
Nome |
DeptNo |
|---|---|
Eve |
100 |
Charlie |
500 |
Alice |
100 |
David |
200 |
Bob |
300 |
EWIs relacionados¶
Sem EWIs relacionados.
Cláusula Expand On¶
Referência de tradução para converter a funcionalidade Teradata Expand On para Snowflake
Descrição¶
A cláusula Expand On expande uma coluna com um tipo de dados period, criando uma série temporal regular de linhas com base no valor do período na linha de entrada. Para obter mais informações sobre a cláusula Expand On, consulte a documentação do Teradata.
Amostra de padrões da origem¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Amostra de dados¶
Teradata¶
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'
)
);
Snowflake¶
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 ***/!!!);
Cláusula Expand On¶
Suponha que você queira expandir a coluna de período por segundos, pois essa cláusula Expand On tem expansão de período de âncora e expansão de literal de intervalo.
Expansão do período de âncora¶
Teradata¶
SELECT
id,
BEGIN(bg)
FROM
table1 EXPAND ON pd AS bg BY ANCHOR ANCHOR_SECOND;
Resultado¶
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 |
O Snowflake não suporta a cláusula Expand On. Para reproduzir os mesmos resultados e a mesma funcionalidade, o código do Teradata SQL estará contido em um bloco CTE, com uma função EXPAND_ON_UDF e TABLE, usando a função FLATTEN para retornar várias linhas, ROW_COUNT_UDF e DIFF_TTIME_PERIOD_UDF para indicar quantas linhas são necessárias e retornando VALUE para ajudar EXPAND_ON_UDF a calcular as diferentes séries temporais regulares. Esse bloco CTE retorna o mesmo alias de expansão de colunas da cláusula Expand On, de modo que o resultado pode ser usado em qualquer uso do tipo de dados period.
Snowflake¶
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;
Resultado¶
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 |
Problemas conhecidos¶
A cláusula Expand On pode usar expansão literal de intervalo; para este caso, SnowConvert AI adicionará um erro informando que esta tradução está planejada.
Expansão literal do intervalo¶
Teradata¶
SELECT
id,
BEGIN(bg)
FROM
table1 EXPAND ON pd AS bg BY INTERVAL '1' SECOND;
Resultado¶
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 |
Snowflake¶
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 relacionados¶
SSC-EWI-0073: Revisão de equivalência funcional pendente.
SSC-EWI-TD0053: o Snowflake não é compatível com o tipo de dados de período; todos os períodos são tratados como varchar.
Normalize¶
Referência de tradução para converter a funcionalidade Teradata Normalize para Snowflake
Descrição¶
NORMALIZE especifica que os valores de período na coluna do primeiro período que se encontram ou se sobrepõem são combinados para formar um período que engloba os valores de período individuais. Para obter mais informações sobre a cláusula Normalize, consulte a documentação do Teradata.
Amostra de padrões da origem¶
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Amostra de dados¶
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')
);
Snowflake¶
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 ***/!!!);
Cláusula Normalize¶
Suponhamos que você queira usar a cláusula Normalize com o ID de funcionário.
Teradata¶
SELECT
NORMALIZE emp_id,
duration
FROM
project;
Resultado¶
EMP_ID |
DURATION |
|---|---|
20 |
(2010-03-10, 2010-07-20) |
10 |
(2010-01-10, 2010-08-18) |
20 |
(2020-05-10, 2010-09-20) |
Snowflake¶
!!!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;
Resultado¶
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 |
Problemas conhecidos¶
A cláusula Normalize pode usar ON MEETS OR OVERLAPS, ON OVERLAPS ou ON OVERLAPS OR MEETS, para esses casos, o SnowConvert AI adicionará um erro informando que esta tradução está planejada para o futuro.
Teradata¶
SELECT NORMALIZE ON MEETS OR OVERLAPS emp_id, duration FROM table1;
Snowflake¶
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 relacionados¶
SSC-EWI-0073: Revisão de equivalência funcional pendente.
SSC-EWI-TD0079: A coluna de tipo de período necessária não foi encontrada.
SSC-EWI-TD0053: o Snowflake não é compatível com o tipo de dados de período; todos os períodos são tratados como varchar.
Reset When¶
Descrição¶
Reset When determina a partição na qual uma função da janela SQL opera com base em alguma condição específica. Se a condição for avaliada como True, uma nova subpartição dinâmica será criada dentro da partição de janela existente. Para obter mais informações sobre Reset When, consulte a documentação do Teradata em .
Amostra de padrões da origem¶
Amostra de dados¶
Teradata¶
Query
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);
Result
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¶
Query
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);
Result
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¶
Para cada conta, suponha que você queira analisar a sequência de aumentos consecutivos do saldo mensal. Quando o saldo de um mês é menor ou igual ao saldo do mês anterior, a exigência é zerar o contador e reiniciar.
Para analisar esses dados, o Teradata SQL usa uma função de janela com um agregado aninhado e uma instrução Reset When, como segue:
Teradata¶
Query
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;
Result
| 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¶
O Snowflake não suporta a cláusula Reset When em funções de janela. Para reproduzir o mesmo resultado, o código do Teradata SQL deve ser convertido usando a sintaxe nativa do SQL e subconsultas aninhadas, como segue:
Query
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;
Result
| 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 |
Duas subconsultas aninhadas são necessárias para dar suporte à funcionalidade Reset When no Snowflake.
Na subconsulta interna, um indicador de partição dinâmica (dynamic_part) é criado e preenchido. dynamic_part é definido como 1 se o saldo de um mês for menor ou igual ao saldo do mês anterior; caso contrário, é definido como 0.
Na próxima camada, um atributo new_dynamic_part é gerado como resultado de uma função de janela SUM.
Por fim, new_dynamic\_part é adicionado como um novo atributo de partição (partição dinâmica) ao atributo de partição existente (account_id) e aplica a mesma função de janela ROW_NUMBER() que no Teradata.
Após essas alterações, o Snowflake gera o mesmo resultado que o Teradata.
Reset When quando a função de janela condicional é uma coluna¶
O mesmo exemplo acima, exceto que agora a função de janela usada na condição RESET WHEN é definida como uma coluna chamada previous. Essa variação altera ligeiramente a transformação, pois não é mais necessário definir previous_value como no exemplo anterior. É a mesma solução alternativa.
Teradata¶
Query
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;
Result
| 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¶
Query
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;
Untitled
| 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 |
Problemas conhecidos¶
A cláusula RESET WHEN poderia ter algumas variações, como sua condição. Atualmente, o SnowConvert AI só oferece suporte a condições binárias (<=, >=, <> ou =). Em qualquer outro tipo, como IS NOT NULL, o SnowConvert AI removerá a cláusula RESET WHEN e adicionará uma mensagem de erro, pois não é compatível no Snowflake, conforme mostrado no exemplo a seguir.
Teradata¶
Query
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¶
Query
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 relacionados¶
SSC-EWI-TD0077: A cláusula RESET WHEN não é suportada neste cenário devido à sua condição.
Cláusula SAMPLE¶
Descrição¶
A cláusula SAMPLE no Teradata reduz o número de linhas a serem processadas e retorna uma ou mais amostras de linhas como uma lista de frações ou como uma lista de números de linhas. A cláusula é usada na consulta SELECT. Para obter mais informações, consulte a seguinte documentação do Teradata.
Sintaxe do Teradata
SAMPLE
[ WITH REPLACEMENT ]
[ RANDOMIZED LOCALIZATION ]
{ { fraction_description | count_description } [,...] |
when_clause ]
}
Sintaxe do Snowflake
Consulte a documentação do Snowflake a seguir para obter mais informações. SAMPLE e TABLESAMPLE são sinônimos.
SELECT ...
FROM ...
{ SAMPLE | TABLESAMPLE } [ samplingMethod ]
[ ... ]
Onde:
samplingMethod ::= {
{ BERNOULLI | ROW } ( { <probability> | <num> ROWS } ) |
{ SYSTEM | BLOCK } ( <probability> ) [ { REPEATABLE | SEED } ( <seed> ) ] }
No Snowflake, as seguintes palavras-chave podem ser usadas de forma intercambiável:
SAMPLE | TABLESAMPLEBERNOULLI | ROWSYSTEM | BLOCKREPEATABLE | SEED
Analise a tabela a seguir para verificar as principais diferenças.
Comportamento de SAMPLE |
Teradata |
Snowflake |
|---|---|---|
Amostra por probabilidade |
Também conhecido como descrição da fração. Deve ser um número fracionário entre 0,1 e 1. |
Número decimal entre 0 e 100. |
Número fixo de linhas |
Também conhecido como descrição da contagem. É um número inteiro positivo que determina o número de linhas a serem amostradas. |
Especifica o número de linhas (até 1.000.000) a serem amostradas na tabela. Pode ser qualquer número inteiro entre |
Linhas repetidas |
É conhecido como |
É conhecido como |
Métodos de amostragem |
Proporcional e |
|
Amostra de padrões da origem¶
Amostra de dados¶
Teradata¶
Query
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¶
Query
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);
Cláusula SAMPLE¶
Número fixo de linhas¶
Observe que, neste exemplo, o número de linhas é um número fixo, mas não necessariamente o mesmo resultado para cada execução.
Teradata
Entrada
SELECT * FROM Employee SAMPLE 2;
Saída 2 linhas.
Snowflake
Entrada
SELECT * FROM Employee SAMPLE (2 ROWS);
Saída 2 linhas.
Número de linhas baseado na probabilidade¶
Essa opção retornará uma variedade de linhas, dependendo do conjunto de probabilidade.
Teradata
Entrada
SELECT * FROM Employee SAMPLE 0.25;
Saída 25% de probabilidade para cada linha: 1 linha de saída.
Snowflake
Entrada
SELECT * FROM Employee SAMPLE (25);
Saída 25% de probabilidade para cada linha: 1 linha de saída.
Problemas conhecidos¶
Número fixo de linhas com substituição¶
Essa opção retornará um número fixo de linhas e permitirá a repetição das linhas. No Snowflake, não é possível solicitar mais amostras do que linhas em uma tabela.
Amostra da Teradata
Entrada
SELECT * FROM Employee SAMPLE WITH REPLACEMENT 8;
Saída
EmpNo |
Nome |
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 |
Amostragem condicional¶
No Snowflake, não há amostragem condicional. Isso pode ser feito usando CTE’s.
Amostra da Teradata
Entrada
SELECT * FROM employee
SAMPLE WHEN DeptNo > 100 then 0.9
ELSE 0.1 END;
Saída
EmpNo |
Nome |
DeptNo |
|---|---|---|
3 |
Charlie |
500 |
4 |
David |
200 |
2 |
Bob |
300 |
EWIs relacionados¶
SSC-EWI-0021: Sintaxe não suportada no Snowflake.