Funções de janela¶
Uma função de janela opera em um grupo (“janela”) de linhas relacionadas.
Cada vez que uma função de janela é chamada, são passadas uma linha (a linha atual na janela) e a janela das linhas que contêm a linha atual. A função de janela retorna uma linha de saída para cada linha de entrada. A saída depende da linha individual passada para a função e dos valores das outras linhas na janela passada para a função.
Algumas funções de janela diferenciam a ordem. Há dois tipos principais de funções de janela que diferenciam a ordem:
Funções relacionadas à classificação.
Funções de quadro de janela.
As informações da lista de funções relacionadas à classificação são baseadas no “ranking” de uma linha. Por exemplo, se você classificar as lojas em ordem decrescente por lucro anual, a loja com o maior lucro será classificada 1; a segunda loja mais lucrativa será classificada 2 e assim por diante.
As funções de quadro de janela permitem realizar operações contínuas, como o cálculo de um total em execução ou uma média móvel, em um subconjunto das linhas na janela.
Os usuários que não estão familiarizados com as funções de janela, funções relacionadas à classificação ou funções de estrutura de janela podem ler o material com os conceitos em Uso de funções de janela.
Neste tópico:
Visão geral¶
O que é uma janela?¶
Uma janela é um grupo de linhas relacionadas. Por exemplo, uma janela pode ser definida com base em carimbos de data/hora, com todas as linhas de um mesmo mês agrupadas na mesma janela. Ou uma janela pode ser definida com base na localização, com todas as linhas de uma determinada cidade agrupadas na mesma janela.
Uma janela pode conter zero, uma ou várias linhas. Para simplificar, a documentação do Snowflake geralmente diz que uma janela contém várias linhas.
O que é uma função de janela?¶
Uma função de janela é qualquer função que opera em uma janela de linhas.
Uma função de janela é geralmente passada por dois parâmetros:
Uma linha. Mais precisamente, são passadas 0 ou mais expressões a uma função de janela. Em quase todos os casos, pelo menos uma dessas expressões faz referência a uma coluna naquela linha. (A maioria das funções de janela requer pelo menos uma coluna ou expressão, mas algumas funções de janela, como algumas funções relacionadas à classificação, não exigem uma coluna ou expressão explícita).
Uma janela de linhas relacionadas que inclui essa linha. A janela pode ser a tabela inteira ou um subconjunto das linhas da tabela.
Para funções que não são de janela, todos os argumentos são geralmente passados explicitamente para a função, por exemplo:
MY_FUNCTION(argument1, argument2, …)
As funções de janela se comportam de maneira diferente; embora a linha atual seja passada como argumento da forma normal, a janela é passada por meio de uma cláusula separada, chamada de cláusula
OVER
. A sintaxe da cláusulaOVER
está documentada posteriormente.
Lista de funções que oferecem suporte a janelas¶
A lista abaixo mostra todas as funções de janela.
Observe que algumas funções listadas como funções de quadro de janela não aceitam todos os tipos possíveis de quadros de janela.
Nome da função |
Janela |
Quadro de janela |
Relacionada à classificação |
Notas |
---|---|---|---|---|
Janela geral |
||||
✔ |
||||
✔ |
✔ |
|||
✔ |
||||
✔ |
||||
✔ |
||||
✔ |
✔ |
|||
✔ |
✔ |
|||
✔ |
||||
✔ |
||||
✔ |
Não utiliza a sintaxe de janela padrão. |
|||
✔ |
✔ |
|||
✔ |
||||
✔ |
✔ |
|||
✔ |
||||
✔ |
Utiliza uma sintaxe diferente das outras funções de janela. |
|||
✔ |
Utiliza uma sintaxe diferente das outras funções de janela. |
|||
✔ |
||||
✔ |
✔ |
STDDEV e STDDEV_SAMP são aliases. |
||
✔ |
✔ |
|||
✔ |
✔ |
|||
✔ |
✔ |
|||
✔ |
✔ |
|||
✔ |
✔ |
Alias para VAR_POP. |
||
✔ |
✔ |
Alias para VAR_SAMP. |
||
Relacionadas à classificação |
||||
✔ |
✔ |
|||
✔ |
✔ |
✔ |
||
✔ |
✔ |
✔ |
||
✔ |
✔ |
|||
✔ |
✔ |
✔ |
||
✔ |
✔ |
|||
✔ |
✔ |
✔ |
||
✔ |
✔ |
|||
✔ |
✔ |
✔ |
Aceita quadros de janela cumulativas com base em intervalos, mas não outros tipos de quadros de janelas. |
|
✔ |
✔ |
✔ |
||
✔ |
✔ |
|||
Agregação bit a bit |
||||
✔ |
||||
✔ |
||||
✔ |
||||
Agregação booleana |
||||
✔ |
||||
✔ |
||||
✔ |
||||
Hash |
||||
✔ |
||||
Agregação de dados semiestruturados |
||||
✔ |
||||
✔ |
||||
Contagem de valores distintos |
||||
✔ |
||||
✔ |
||||
Regressão linear |
||||
✔ |
||||
✔ |
||||
✔ |
||||
✔ |
||||
✔ |
||||
✔ |
||||
✔ |
||||
✔ |
||||
✔ |
||||
Estatística e probabilidade |
||||
✔ |
||||
Estimativa de cardinalidade . (usando HyperLogLog) |
||||
✔ |
Alias para HLL. |
|||
✔ |
||||
✔ |
||||
✔ |
||||
Não é uma função de agregação; utiliza entrada escalar de HLL_ACCUMULATE ou HLL_COMBINE. |
||||
✔ |
||||
✔ |
||||
Estimativa de similaridade . (usando MinHash) |
||||
✔ |
Alias para APPROXIMATE_SIMILARITY. |
|||
✔ |
||||
✔ |
||||
✔ |
||||
Estimativa de frequência . (usando Space-Saving) |
||||
✔ |
||||
✔ |
||||
✔ |
||||
Não é uma função de agregação; utiliza entrada escalar de APPROX_TOP_K_ACCUMULATE ou APPROX_TOP_K_COMBINE. |
||||
Estimativa percentil . (usando t-Digest) |
||||
✔ |
||||
✔ |
||||
✔ |
||||
Não é uma função de agregação; utiliza entrada escalar de APPROX_PERCENTILE_ACCUMULATE ou APPROX_PERCENTILE_COMBINE. |
Funções de janela e valores NULL¶
Algumas funções ignoram valores NULL. Por exemplo, AVG calcula a média dos valores 1
, 5
e NULL
para ser 3
, com base na seguinte fórmula:
(1 + 5) / 2 = 3
Tanto no numerador como no denominador, somente os valores nãoNULL são utilizados.
Se todos os valores passados para a função forem NULL, então a função retorna NULL.
Mais de uma coluna pode ser passada para algumas funções de janela. Por exemplo:
SELECT COUNT(col1, col2) FROM table1;
Nesses casos, a função ignora uma linha se alguma coluna individual for NULL.
Por exemplo, na consulta seguinte, COUNT retorna 1
, não 4
, porque três das quatro linhas contêm pelo menos um valor NULL nas colunas selecionadas:
Crie uma tabela e preencha-a com valores:
CREATE TABLE t (x INT, y INT); INSERT INTO t (x, y) VALUES (1, 2), -- No NULLs. (3, NULL), -- One but not all columns are NULL. (NULL, 6), -- One but not all columns are NULL. (NULL, NULL); -- All columns are NULL.Consultar a tabela:
SELECT COUNT(x, y) FROM t; +-------------+ | COUNT(X, Y) | |-------------| | 1 | +-------------+
Da mesma forma, se SUM é chamado com uma expressão que faz referência a duas ou mais colunas, e se uma ou mais dessas colunas é NULL, a expressão avalia para NULL, e a linha é ignorada:
SELECT SUM(x + y) FROM t; +------------+ | SUM(X + Y) | |------------| | 3 | +------------+
Observe que esse comportamento difere do comportamento de GROUP BY, que não descarta linhas quando algumas colunas são NULL:
SELECT x AS X_COL, y AS Y_COL FROM t GROUP BY x, y; +-------+-------+ | X_COL | Y_COL | |-------+-------| | 1 | 2 | | 3 | NULL | | NULL | 6 | | NULL | NULL | +-------+-------+
Exemplo introdutório¶
Suponha que você seja proprietário de uma rede de lojas. A consulta seguinte mostra a porcentagem do lucro total da rede gerada por cada loja. A consulta utiliza a função RATIO_TO_REPORT
, que toma um valor (por exemplo, net_profit) da linha atual e o divide pela soma dos valores correspondentes (net_profit) de todas as outras linhas:
Criar e carregar a tabela:
CREATE TRANSIENT TABLE store_sales ( branch_ID INTEGER, city VARCHAR, gross_sales NUMERIC(9, 2), gross_costs NUMERIC(9, 2), net_profit NUMERIC(9, 2) ); INSERT INTO store_sales (branch_ID, city, gross_sales, gross_costs) VALUES (1, 'Vancouver', 110000, 100000), (2, 'Vancouver', 140000, 125000), (3, 'Montreal', 150000, 140000), (4, 'Montreal', 155000, 146000); UPDATE store_sales SET net_profit = gross_sales - gross_costs;Consultar a tabela:
SELECT branch_ID, net_profit, 100 * RATIO_TO_REPORT(net_profit) OVER () AS percent_of_chain_profit FROM store_sales AS s1 ORDER BY branch_ID; +-----------+------------+-------------------------+ | BRANCH_ID | NET_PROFIT | PERCENT_OF_CHAIN_PROFIT | |-----------+------------+-------------------------| | 1 | 10000.00 | 22.72727300 | | 2 | 15000.00 | 34.09090900 | | 3 | 10000.00 | 22.72727300 | | 4 | 9000.00 | 20.45454500 | +-----------+------------+-------------------------+
O que é um quadro de janela?¶
Um quadro de janela é um subgrupo das linhas em uma janela. A criação de subconjuntos permite calcular valores considerando apenas aquele subgrupo de linhas especificado. Os quadros de janela são especificados como uma subcláusula adicional na subcláusula ORDER BY
da cláusula OVER
.
Tipos de quadros de janela¶
O Snowflake oferece suporte a dois tipos de quadros de janela:
- Cumulativo:
Permite calcular os valores contínuos do início da janela até a linha atual ou da linha atual até o final da janela.
- Deslizante:
Permite calcular valores contínuos entre quaisquer duas linhas (inclusive) na janela, em relação à linha atual.
Para obter mais informações sobre quadros de janela, incluindo a sintaxe usada para quadros de janela, consulte Sintaxe e utilização do quadro de janela.
Sintaxe e utilização da janela¶
Sintaxe da janela¶
<function> ( [ <arguments> ] ) OVER ( [ PARTITION BY <expr1> ] [ ORDER BY <expr2> ] )
A cláusula OVER
especifica que a função está sendo usada como uma função de janela.
A subcláusula PARTITION BY
permite agrupar as linhas em subgrupos, por exemplo, por cidade, por ano etc. A cláusula PARTITION BY
é opcional. Você pode analisar um grupo inteiro de linhas sem dividi-lo em subgrupos.
A cláusula ORDER BY
ordena as linhas dentro da janela. (Isso é diferente de ordenar a saída de uma consulta. Uma consulta pode ter uma cláusula ORDER BY
que controla a ordem das linhas dentro de uma janela, e uma cláusula ORDER BY
separada, fora da cláusula OVER
, que controla a ordem de saída de toda a consulta). Embora a cláusula ORDER BY
seja opcional para algumas funções de janela, ela é necessária para outras. Por exemplo, as funções de quadro de janela e funções relacionadas à classificação exigem que os dados estejam em uma ordem significativa e, portanto, exigem uma subcláusula ORDER BY
.
Nota
As funções que aceitam quadros de janela utilizam uma sintaxe modificada/alterada. Para obter mais detalhes, consulte Sintaxe e utilização do quadro de janela (neste tópico).
Notas de uso da janela¶
A cláusula
OVER
especifica a janela sobre a qual a função opera. A cláusula consiste em um dos seguintes componentes (ou ambos):PARTITION BY expr1
: subcláusula que define a partição, se houver, para a janela (ou seja, como os dados serão agrupados antes da aplicação da função).ORDER BY expr2
: subcláusula que determina a ordenação das linhas na janela.A subcláusula
ORDER BY
segue regras semelhantes às da cláusulaORDER BY
de consulta, por exemplo, com respeito a ASC/DESC (crescente/decrescente) e tratamento de NULL. Para obter mais detalhes sobre as opções adicionais com suporte, consulte a construção de consulta ORDER BY.Funções diferentes tratam a cláusula
ORDER BY
de maneiras distintas:Algumas funções de janela requerem uma cláusula ORDER BY.
Algumas funções de janela proíbem uma cláusula ORDER BY.
Algumas funções de janela utilizam uma cláusula ORDER BY se ela estiver presente, mas não a exigem.
Algumas funções de janela tratam uma cláusula ORDER BY como uma cláusula de quadro de janela cumulativo implícito. (Mais informações sobre quadros de janelas implícitos estão em Notas de uso dos quadros de janela).
Nota
Para maior clareza, o Snowflake recomenda evitar quadros de janelas implícitos. Se sua consulta utiliza um quadro de janela, faça com que ele seja um quadro de janela explícito.
Sintaxe e utilização do quadro de janela¶
Sintaxe do quadro de janela¶
<function> ( <arguments> ) OVER ( [ PARTITION BY <expr1> ] ORDER BY <expr2> [ cumulativeFrame | slidingFrame ] )
Onde:
cumulativeFrame ::= { { ROWS | RANGE } BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW | { ROWS | RANGE } BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING }slidingFrame ::= { ROWS BETWEEN <N> { PRECEDING | FOLLOWING } AND <N> { PRECEDING | FOLLOWING } | ROWS BETWEEN UNBOUNDED PRECEDING AND <N> { PRECEDING | FOLLOWING } | ROWS BETWEEN <N> { PRECEDING | FOLLOWING } AND UNBOUNDED FOLLOWING }
Nota
Os quadros de janela exigem que os dados na janela estejam em uma ordem conhecida. Portanto, a cláusula ORDER BY dentro da cláusula OVER é obrigatória para a sintaxe do quadro de janela, mesmo que essa cláusula ORDER BY seja opcional na sintaxe geral da função de janela.
Notas de uso dos quadros de janela¶
Para quadros de janela cumulativos:
ROWS
calcula o resultado para a linha atual usando todas as linhas desde o início ou fim da partição até a linha atual (de acordo com a subcláusulaORDER BY
especificada).RANGE
é semelhante aROWS
, exceto que apenas calcula o resultado para linhas que têm o mesmo valor da linha atual (de acordo com a subcláusulaORDER BY
especificada).
Para quadros de janela deslizantes:
ROWS
é inclusivo e é sempre relativo à linha atual.RANGE
não é suportado.Se o número especificado de
ROWS
precedentes ou posteriores se estender além dos limites da janela, o Snowflake trata o valor como NULL.
Se nenhum quadro de janela for especificado, o padrão depende da função:
Para funções não relacionadas à classificação (COUNT, MAX, MIN, SUM), o padrão é o seguinte quadro de janela cumulativo (de acordo com o padrão ANSI):
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
Para funções relacionadas à classificação (FIRST_VALUE, LAST_VALUE, NTH_VALUE), o padrão é a janela inteira:
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
Note que isso diverge do padrão ANSI.
Dicas gerais¶
A sintaxe mostra todas as subcláusulas da cláusula
OVER
como opcionais para funções de janela. Isso é por design (ou seja, você pode usarOVER
sem uma subcláusula dentro dos parênteses). Isso pode ser útil em cenários específicos (por exemplo, desativação do processamento paralelo).PARTITION BY
nem sempre é compatível com GROUP BY.Se uma consulta usa mais de uma função de janela, ela costuma dividir o conjunto de dados de entrada de cada função da mesma forma. Por exemplo, a primeira instrução abaixo tem mais probabilidade de estar correta do que a segunda instrução:
SELECT SUM(a) OVER (PARTITION BY x), SUM(b) OVER (PARTITION BY x) ... ; SELECT SUM(a) , SUM(b) OVER (PARTITION BY x) ... ;
A mensagem de erro
SQL compilation error: ... is not a valid group by expression
é geralmente um sinal de que colunas diferentes nas cláusulas “project” da instrução SELECT não estão divididas da mesma maneira e, portanto, podem produzir números diferentes de linhas.
Exemplos¶
Exemplos adicionais podem ser encontrados em Uso de funções de janela.
Exemplos de quadro de janela cumulativo¶
Criar e preencher uma tabela com valores:
CREATE OR REPLACE TABLE example_cumulative (p INT, o INT, i INT);
INSERT INTO example_cumulative VALUES
( 0, 1, 10), (0, 2, 20), (0, 3, 30),
(100, 1, 10),(100, 2, 30),(100, 2, 5),(100, 3, 11),(100, 3, 120),
(200, 1, 10000),(200, 1, 200),(200, 1, 808080),(200, 2, 33333),(200, 3, null), (200, 3, 4),
(300, 1, null), (300, 1, null);
Executar uma consulta que utilize um quadro de janela cumulativo e mostre a saída. Retornar count, sum, min e max cumulativos para as linhas na janela especificada para a tabela:
SELECT
p, o, i,
COUNT(i) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) count_i_Rows_Pre,
SUM(i) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) sum_i_Rows_Pre,
AVG(i) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) avg_i_Rows_Pre,
MIN(i) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) min_i_Rows_Pre,
MAX(i) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) max_i_Rows_Pre
FROM example_cumulative
ORDER BY p,o;
+-----+---+--------+------------------+----------------+----------------+----------------+----------------+
| P | O | I | COUNT_I_ROWS_PRE | SUM_I_ROWS_PRE | AVG_I_ROWS_PRE | MIN_I_ROWS_PRE | MAX_I_ROWS_PRE |
|-----+---+--------+------------------+----------------+----------------+----------------+----------------|
| 0 | 1 | 10 | 1 | 10 | 10.000 | 10 | 10 |
| 0 | 2 | 20 | 2 | 30 | 15.000 | 10 | 20 |
| 0 | 3 | 30 | 3 | 60 | 20.000 | 10 | 30 |
| 100 | 1 | 10 | 1 | 10 | 10.000 | 10 | 10 |
| 100 | 2 | 30 | 2 | 40 | 20.000 | 10 | 30 |
| 100 | 2 | 5 | 3 | 45 | 15.000 | 5 | 30 |
| 100 | 3 | 11 | 4 | 56 | 14.000 | 5 | 30 |
| 100 | 3 | 120 | 5 | 176 | 35.200 | 5 | 120 |
| 200 | 1 | 10000 | 1 | 10000 | 10000.000 | 10000 | 10000 |
| 200 | 1 | 200 | 2 | 10200 | 5100.000 | 200 | 10000 |
| 200 | 1 | 808080 | 3 | 818280 | 272760.000 | 200 | 808080 |
| 200 | 2 | 33333 | 4 | 851613 | 212903.250 | 200 | 808080 |
| 200 | 3 | NULL | 4 | 851613 | 212903.250 | 200 | 808080 |
| 200 | 3 | 4 | 5 | 851617 | 170323.400 | 4 | 808080 |
| 300 | 1 | NULL | 0 | NULL | NULL | NULL | NULL |
| 300 | 1 | NULL | 0 | NULL | NULL | NULL | NULL |
+-----+---+--------+------------------+----------------+----------------+----------------+----------------+
Retornar count, sum, min e max cumulativos por intervalo para as linhas na janela especificada para a tabela:
SELECT
p, o, i,
COUNT(i) OVER (PARTITION BY p ORDER BY o RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) count_i_Range_Pre,
SUM(i) OVER (PARTITION BY p ORDER BY o RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) sum_i_Range_Pre,
AVG(i) OVER (PARTITION BY p ORDER BY o RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) avg_i_Range_Pre,
MIN(i) OVER (PARTITION BY p ORDER BY o RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) min_i_Range_Pre,
MAX(i) OVER (PARTITION BY p ORDER BY o RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) max_i_Range_Pre
FROM example_cumulative
ORDER BY p,o;
+-----+---+--------+-------------------+-----------------+-----------------+-----------------+-----------------+
| P | O | I | COUNT_I_RANGE_PRE | SUM_I_RANGE_PRE | AVG_I_RANGE_PRE | MIN_I_RANGE_PRE | MAX_I_RANGE_PRE |
|-----+---+--------+-------------------+-----------------+-----------------+-----------------+-----------------|
| 0 | 1 | 10 | 1 | 10 | 10.000000 | 10 | 10 |
| 0 | 2 | 20 | 2 | 30 | 15.000000 | 10 | 20 |
| 0 | 3 | 30 | 3 | 60 | 20.000000 | 10 | 30 |
| 100 | 1 | 10 | 1 | 10 | 10.000000 | 10 | 10 |
| 100 | 2 | 30 | 3 | 45 | 15.000000 | 5 | 30 |
| 100 | 2 | 5 | 3 | 45 | 15.000000 | 5 | 30 |
| 100 | 3 | 11 | 5 | 176 | 35.200000 | 5 | 120 |
| 100 | 3 | 120 | 5 | 176 | 35.200000 | 5 | 120 |
| 200 | 1 | 10000 | 3 | 818280 | 272760.000000 | 200 | 808080 |
| 200 | 1 | 200 | 3 | 818280 | 272760.000000 | 200 | 808080 |
| 200 | 1 | 808080 | 3 | 818280 | 272760.000000 | 200 | 808080 |
| 200 | 2 | 33333 | 4 | 851613 | 212903.250000 | 200 | 808080 |
| 200 | 3 | NULL | 5 | 851617 | 170323.400000 | 4 | 808080 |
| 200 | 3 | 4 | 5 | 851617 | 170323.400000 | 4 | 808080 |
| 300 | 1 | NULL | 0 | NULL | NULL | NULL | NULL |
| 300 | 1 | NULL | 0 | NULL | NULL | NULL | NULL |
+-----+---+--------+-------------------+-----------------+-----------------+-----------------+-----------------+
Retornar os mesmos resultados da consulta acima usando a semântica padrão de quadro de janela (ou seja, RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
):
SELECT
p, o, i,
COUNT(i) OVER (PARTITION BY p ORDER BY o) count_i_Range_Pre,
SUM(i) OVER (PARTITION BY p ORDER BY o) sum_i_Range_Pre,
AVG(i) OVER (PARTITION BY p ORDER BY o) avg_i_Range_Pre,
MIN(i) OVER (PARTITION BY p ORDER BY o) min_i_Range_Pre,
MAX(i) OVER (PARTITION BY p ORDER BY o) max_i_Range_Pre
FROM example_cumulative
ORDER BY p,o;
+-----+---+--------+-------------------+-----------------+-----------------+-----------------+-----------------+
| P | O | I | COUNT_I_RANGE_PRE | SUM_I_RANGE_PRE | AVG_I_RANGE_PRE | MIN_I_RANGE_PRE | MAX_I_RANGE_PRE |
|-----+---+--------+-------------------+-----------------+-----------------+-----------------+-----------------|
| 0 | 1 | 10 | 1 | 10 | 10.000000 | 10 | 10 |
| 0 | 2 | 20 | 2 | 30 | 15.000000 | 10 | 20 |
| 0 | 3 | 30 | 3 | 60 | 20.000000 | 10 | 30 |
| 100 | 1 | 10 | 1 | 10 | 10.000000 | 10 | 10 |
| 100 | 2 | 30 | 3 | 45 | 15.000000 | 5 | 30 |
| 100 | 2 | 5 | 3 | 45 | 15.000000 | 5 | 30 |
| 100 | 3 | 11 | 5 | 176 | 35.200000 | 5 | 120 |
| 100 | 3 | 120 | 5 | 176 | 35.200000 | 5 | 120 |
| 200 | 1 | 10000 | 3 | 818280 | 272760.000000 | 200 | 808080 |
| 200 | 1 | 200 | 3 | 818280 | 272760.000000 | 200 | 808080 |
| 200 | 1 | 808080 | 3 | 818280 | 272760.000000 | 200 | 808080 |
| 200 | 2 | 33333 | 4 | 851613 | 212903.250000 | 200 | 808080 |
| 200 | 3 | NULL | 5 | 851617 | 170323.400000 | 4 | 808080 |
| 200 | 3 | 4 | 5 | 851617 | 170323.400000 | 4 | 808080 |
| 300 | 1 | NULL | 0 | NULL | NULL | NULL | NULL |
| 300 | 1 | NULL | 0 | NULL | NULL | NULL | NULL |
+-----+---+--------+-------------------+-----------------+-----------------+-----------------+-----------------+
Exemplos de quadro de janela deslizante¶
Criar e preencher uma tabela com valores:
CREATE TABLE example_sliding
(p INT, o INT, i INT, r INT, s VARCHAR(100));
INSERT INTO example_sliding VALUES
(100,1,1,70,'seventy'),(100,2,2,30, 'thirty'),(100,3,3,40,'forty'),(100,4,NULL,90,'ninety'),
(100,5,5,50,'fifty'),(100,6,6,30,'thirty'),
(200,7,7,40,'forty'),(200,8,NULL,NULL,'n_u_l_l'),(200,9,NULL,NULL,'n_u_l_l'),(200,10,10,20,'twenty'),
(200,11,NULL,90,'ninety'),
(300,12,12,30,'thirty'),
(400,13,NULL,20,'twenty');
Retornar os valores mínimos para duas colunas (numérica e cadeia de caracteres) em janelas deslizantes antes, depois e englobando a linha atual:
select p, o, i AS i_col,
MIN(i) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING) min_i_3P_1P,
MIN(i) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 1 FOLLOWING AND 3 FOLLOWING) min_i_1F_3F,
MIN(i) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 1 PRECEDING AND 3 FOLLOWING) min_i_1P_3F,
s,
MIN(s) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING) min_s_3P_1P,
MIN(s) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 1 FOLLOWING AND 3 FOLLOWING) min_s_1F_3F,
MIN(s) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 1 PRECEDING AND 3 FOLLOWING) min_s_1P_3F
FROM example_sliding
ORDER BY p, o;
+-----+----+-------+-------------+-------------+-------------+---------+-------------+-------------+-------------+
| P | O | I_COL | MIN_I_3P_1P | MIN_I_1F_3F | MIN_I_1P_3F | S | MIN_S_3P_1P | MIN_S_1F_3F | MIN_S_1P_3F |
|-----+----+-------+-------------+-------------+-------------+---------+-------------+-------------+-------------|
| 100 | 1 | 1 | NULL | 2 | 1 | seventy | NULL | forty | forty |
| 100 | 2 | 2 | 1 | 3 | 1 | thirty | seventy | fifty | fifty |
| 100 | 3 | 3 | 1 | 5 | 2 | forty | seventy | fifty | fifty |
| 100 | 4 | NULL | 1 | 5 | 3 | ninety | forty | fifty | fifty |
| 100 | 5 | 5 | 2 | 6 | 5 | fifty | forty | thirty | fifty |
| 100 | 6 | 6 | 3 | NULL | 5 | thirty | fifty | NULL | fifty |
| 200 | 7 | 7 | NULL | 10 | 7 | forty | NULL | n_u_l_l | forty |
| 200 | 8 | NULL | 7 | 10 | 7 | n_u_l_l | forty | n_u_l_l | forty |
| 200 | 9 | NULL | 7 | 10 | 10 | n_u_l_l | forty | ninety | n_u_l_l |
| 200 | 10 | 10 | 7 | NULL | 10 | twenty | forty | ninety | n_u_l_l |
| 200 | 11 | NULL | 10 | NULL | 10 | ninety | n_u_l_l | NULL | ninety |
| 300 | 12 | 12 | NULL | NULL | 12 | thirty | NULL | NULL | thirty |
| 400 | 13 | NULL | NULL | NULL | NULL | twenty | NULL | NULL | twenty |
+-----+----+-------+-------------+-------------+-------------+---------+-------------+-------------+-------------+
Retornar os valores máximos para duas colunas (numérica e cadeia de caracteres) em janelas deslizantes antes, depois e englobando a linha atual:
SELECT p, o, i AS i_col,
MAX(i) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING) max_i_3P_1P,
MAX(i) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 1 FOLLOWING AND 3 FOLLOWING) max_i_1F_3F,
MAX(i) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 1 PRECEDING AND 3 FOLLOWING) max_i_1P_3F,
s,
MAX(s) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING) max_s_3P_1P,
MAX(s) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 1 FOLLOWING AND 3 FOLLOWING) max_s_1F_3F,
MAX(s) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 1 PRECEDING AND 3 FOLLOWING) max_s_1P_3F
FROM example_sliding
ORDER BY p, o;
+-----+----+-------+-------------+-------------+-------------+---------+-------------+-------------+-------------+
| P | O | I_COL | MAX_I_3P_1P | MAX_I_1F_3F | MAX_I_1P_3F | S | MAX_S_3P_1P | MAX_S_1F_3F | MAX_S_1P_3F |
|-----+----+-------+-------------+-------------+-------------+---------+-------------+-------------+-------------|
| 100 | 1 | 1 | NULL | 3 | 3 | seventy | NULL | thirty | thirty |
| 100 | 2 | 2 | 1 | 5 | 5 | thirty | seventy | ninety | thirty |
| 100 | 3 | 3 | 2 | 6 | 6 | forty | thirty | thirty | thirty |
| 100 | 4 | NULL | 3 | 6 | 6 | ninety | thirty | thirty | thirty |
| 100 | 5 | 5 | 3 | 6 | 6 | fifty | thirty | thirty | thirty |
| 100 | 6 | 6 | 5 | NULL | 6 | thirty | ninety | NULL | thirty |
| 200 | 7 | 7 | NULL | 10 | 10 | forty | NULL | twenty | twenty |
| 200 | 8 | NULL | 7 | 10 | 10 | n_u_l_l | forty | twenty | twenty |
| 200 | 9 | NULL | 7 | 10 | 10 | n_u_l_l | n_u_l_l | twenty | twenty |
| 200 | 10 | 10 | 7 | NULL | 10 | twenty | n_u_l_l | ninety | twenty |
| 200 | 11 | NULL | 10 | NULL | 10 | ninety | twenty | NULL | twenty |
| 300 | 12 | 12 | NULL | NULL | 12 | thirty | NULL | NULL | thirty |
| 400 | 13 | NULL | NULL | NULL | NULL | twenty | NULL | NULL | twenty |
+-----+----+-------+-------------+-------------+-------------+---------+-------------+-------------+-------------+
Retornar a soma de uma coluna de números em janelas deslizantes antes, depois e englobando a linha atual:
SELECT p, o, r AS r_col,
SUM(r) OVER (PARTITION BY p ORDER BY o ROWS BETWEEN 4 PRECEDING AND 2 PRECEDING) sum_r_4P_2P,
sum(r) over (partition by p ORDER BY o ROWS BETWEEN 2 FOLLOWING AND 4 FOLLOWING) sum_r_2F_4F,
sum(r) over (partition by p ORDER BY o ROWS BETWEEN 2 PRECEDING AND 4 FOLLOWING) sum_r_2P_4F
FROM example_sliding
ORDER BY p, o;
+-----+----+-------+-------------+-------------+-------------+
| P | O | R_COL | SUM_R_4P_2P | SUM_R_2F_4F | SUM_R_2P_4F |
|-----+----+-------+-------------+-------------+-------------|
| 100 | 1 | 70 | NULL | 180 | 280 |
| 100 | 2 | 30 | NULL | 170 | 310 |
| 100 | 3 | 40 | 70 | 80 | 310 |
| 100 | 4 | 90 | 100 | 30 | 240 |
| 100 | 5 | 50 | 140 | NULL | 210 |
| 100 | 6 | 30 | 160 | NULL | 170 |
| 200 | 7 | 40 | NULL | 110 | 150 |
| 200 | 8 | NULL | NULL | 110 | 150 |
| 200 | 9 | NULL | 40 | 90 | 150 |
| 200 | 10 | 20 | 40 | NULL | 110 |
| 200 | 11 | 90 | 40 | NULL | 110 |
| 300 | 12 | 30 | NULL | NULL | 30 |
| 400 | 13 | 20 | NULL | NULL | 20 |
+-----+----+-------+-------------+-------------+-------------+