SnowConvert: Instrução DML do Teradata¶
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áusulaUSING
para fazer referência às tabelas extras envolvidas na condição.
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;
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¶
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
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;
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 não suportada.
Instrução de atualização¶
Consulte Instrução de atualização
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
-- 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 relacionados¶
Sem EWIs relacionados.
Com modificador¶
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, ele será deixado como o original, sem nenhuma alteração na sequência, conforme detalhado em um exemplo da sequência SSC-EWI-TD0077 No exemplo abaixo, há dois CTEs denominados n1 e n2, sendo que o n1 se refere ao 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
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;
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¶
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 INSERT
que 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 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))));
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 essa instrução é removida da migração porque é uma 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.
INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ERRORS;
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.
INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ALL ERRORS;
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.
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¶
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.
INSERT INTO MY_TABLE
SELECT *
FROM MY_SAMPLE
LOGGING ERRORS WITH LIMIT OF 100;
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 DISTINCT col1, col2 FROM table1
Snowflake
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
SELECT
my_val, sum(col1),
col2 AS my_val FROM table1
Snowflake
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
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> )
Sample Source Patterns
Amostra de dados
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);
Igual a predicado ANY em cláusula 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 |
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
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo < ANY(100,300,500) ;
Nome |
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 na cláusula 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 na cláusula WHERE
Teradata
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN ALL(100, 200);
Nome |
DeptNo |
---|---|
Charlie |
500 |
Bob |
300 |
Snowflake
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN (100, 200);
Nome |
DeptNo |
---|---|
Charlie |
500 |
Bob |
300 |
Known Issues
NOT IN ANY na cláusula WHERE
Teradata
SELECT Name, DeptNo
FROM Employee
WHERE DeptNo NOT IN ANY(100, 200);
Nome |
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);
Nome |
DeptNo |
---|---|
Eve |
100 |
Charlie |
500 |
Alice |
100 |
David |
200 |
Bob |
300 |
Related EWIs
Sem EWIs relacionados.
Cláusula Expand On
Description
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.
Sample Source Patterns
Nota
Algumas partes do código de saída foram omitidas por motivos de clareza.
Amostra de dados¶
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 ***/!!!);
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 Ancoragem
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 |
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.
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 |
Problemas conhecidos¶
A cláusula Expand On pode usar a expansão literal de intervalo; nesse caso, o SnowConvert adicionará um erro informando que essa conversão está planejada.
Expansão literal do intervalo¶
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 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 period; em vez disso, todos os períodos são tratados como varchar.
Normalize¶
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¶
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 ***/!!!);
Cláusula Normalize¶
Suponhamos que você queira usar a cláusula Normalize com o ID de funcionário.
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 |
Problemas conhecidos¶
A cláusula Normalize pode usar ON MEETS OR OVERLAPS, ON OVERLAPS ou ON OVERLAPS OR MEETS, para esses casos o SnowConvert adicionará um erro informando que essa conversão está planejada para o futuro.
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 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 period; em vez disso, 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
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 |
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
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 |
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¶
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
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:
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 |
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
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 |
Problemas conhecidos¶
A cláusula RESET WHEN pode ter algumas variações, como sua condição. Atualmente, o SnowConvert só é compatível com condições binárias (<=, >=, <> ou =), em qualquer outro tipo, como IS NOT NULL
, o SnowConvert removerá a cláusula RESET WHEN e adicionará uma mensagem de erro, pois ela não é compatível com o Snowflake, conforme mostrado no exemplo a seguir.
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 relacionados¶
SSC-EWI-TD0077: a cláusula RESET WHEN não é compatível com esse 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 | TABLESAMPLE
BERNOULLI | ROW
SYSTEM | BLOCK
REPEATABLE | 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
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);
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
SELECT * FROM Employee SAMPLE 2;
2 linhas.
Snowflake
SELECT * FROM Employee SAMPLE (2 ROWS);
2 linhas.
Número de linhas com base na probabilidade
Essa opção retornará uma variedade de linhas, dependendo do conjunto de probabilidade.
Teradata
SELECT * FROM Employee SAMPLE 0.25;
25% de probabilidade para cada linha: 1 linha de saída.
Snowflake
SELECT * FROM Employee SAMPLE (25);
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
SELECT * FROM Employee SAMPLE WITH REPLACEMENT 8;
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 |