📙
Windows Function - Parte III
Módulo SQL Avançado
Aula 34
Created @May 19, 2023 9:58 AM
Material PDF
Done
Reviewed
Objetivo da Aula:
Anatomia
Tipos de funções de agregação
Exercícios
Próxima aula
Conteúdo
1. Anatomia
A sintaxe da Windows Function é da seguinte forma:
SELECT
<columns_1>, <column_2>,
<window_function> ( expression ) OVER ( PARTITION BY <partition_list>
ORDER BY <order_list>
ROWS frame_cause )
FROM <table_name>
2. Tipos de funções de agregação
2.1 Agregação
3.1.1 AVG()
Calcula o preço médio de uma coluna.
Exemplo:
-- Calcular o preço médio por categoria
-- GROUP BY
SELECT
p.product_category_name,
AVG ( oi.price ) AS avg_price
FROM order_items oi INNER JOIN products p ON ( p.product_id = oi.product_id )
WHERE p.product_category_name IS NOT NULL
GROUP BY p.product_category_name
-- Windows Function
SELECT
p.product_category_name,
oi.price,
AVG ( oi.price ) OVER ( PARTITION BY p.product_category_name ) AS avg_price
FROM order_items oi INNER JOIN products p ON ( p.product_id = oi.product_id )
WHERE p.product_category_name IS NOT NULL
Windows Function - Parte III 1
Conteúdo licenciado para -
3.1.2 MAX()
Retorna o maior valor de uma coluna
Exemplo:
-- Calcular o preço médio por categoria e por tipo de pagamento
-- GROUP BY
SELECT
p.product_category_name,
op.payment_type,
MAX ( oi.price ) AS avg_price
FROM order_items oi INNER JOIN products p ON ( p.product_id = oi.product_id )
INNER JOIN order_payments op ON ( op.order_id = oi.order_id)
WHERE p.product_category_name IS NOT NULL
GROUP BY p.product_category_name, op.payment_type
-- Windows Function
SELECT
p.product_category_name,
op.payment_type,
MAX ( oi.price ) OVER ( PARTITION BY p.product_category_name, op.payment_type ) AS avg_price
FROM order_items oi INNER JOIN products p ON ( p.product_id = oi.product_id )
INNER JOIN order_payments op ON ( op.order_id = oi.order_id)
WHERE p.product_category_name IS NOT NULL
3.1.3 MIN()
Retorna o menor valor de uma coluna
Exemplo:
-- Encontrar a data da primeira compra por categoria e tipo de pagamento
-- GROUP BY
SELECT
p.product_category_name,
op.payment_type,
oi.shipping_limit_date,
MIN ( oi.shipping_limit_date ) OVER ( PARTITION BY p.product_category_name, op.payment_type
ORDER BY oi.shipping_limit_date ) AS first_purchase
FROM order_items oi INNER JOIN products p ON ( p.product_id = oi.product_id )
INNER JOIN order_payments op ON ( op.order_id = oi.order_id)
WHERE p.product_category_name IS NOT NULL
2.2 Ranqueamento
3.2.1 ROW_NUMBER( )
Mostra o número da linha, começando com 1 até o valor da última linha de acordo com a ordenação definida dentro
da função janela. Essa função não recebe parâmetros dentro do parênteses.
Exemplo:
SELECT
p.product_category_name,
oi.price,
ROW_NUMBER() OVER (PARTITION BY p.product_category_name ORDER BY oi.price DESC ) AS price_rank
FROM order_items oi INNER JOIN products p ON ( p.product_id = oi.product_id )
WHERE p.product_category_name IS NOT NULL
3.2.2 RANK( )
Se a coluna ranqueada possuir valor iguais, ambos valores recebem o mesmo número do ranking e o próximo valor
recebe o valor do ranking somado ao número de repetições.
Exemplo:
SELECT
p.product_category_name,
oi.price,
RANK() OVER (PARTITION BY p.product_category_name ORDER BY oi.price DESC ) AS price_rank
Windows Function - Parte III 2
Conteúdo licenciado para -
FROM order_items oi INNER JOIN products p ON ( p.product_id = oi.product_id )
WHERE p.product_category_name IS NOT NULL
3.2.3 DENSE_RANK( )
Se a coluna ranqueada possuir valor iguais, ambos valores recebem o mesmo número do ranking e o próximo valor
recebe o valor seguinte do ranking.
Exemplo:
SELECT
p.product_category_name,
oi.price,
DENSE_RANK() OVER (PARTITION BY p.product_category_name ORDER BY oi.price DESC ) AS price_rank
FROM order_items oi INNER JOIN products p ON ( p.product_id = oi.product_id )
WHERE p.product_category_name IS NOT NULL
3.2.4 PERCENT_RANK( )
Essa função mostra o valor percentual do ranking para cada uma das linhas.
Exemplo:
SELECT
p.product_category_name,
oi.price,
PERCENT_RANK() OVER (PARTITION BY p.product_category_name ORDER BY oi.price DESC ) AS price_rank
FROM order_items oi INNER JOIN products p ON ( p.product_id = oi.product_id )
WHERE p.product_category_name IS NOT NULL
3.2.5 NTILE()
Divide os valores da coluna em buckets.
Exemplo:
SELECT
p.product_category_name,
oi.price,
NTILE(4) OVER (PARTITION BY p.product_category_name ORDER BY oi.price DESC ) AS price_rank
FROM order_items oi INNER JOIN products p ON ( p.product_id = oi.product_id )
WHERE p.product_category_name IS NOT NULL
2.3 Valor
3.3.1 LAG()
Causa um deslocamento adiantado, avançando os valores da coluna.
Exemplo:
SELECT
p.product_category_name,
oi.price,
oi.shipping_limit_date,
LAG( oi.shipping_limit_date ) OVER ( PARTITION BY p.product_category_name
ORDER BY oi.shipping_limit_date DESC ) AS lag
FROM order_items oi INNER JOIN products p ON ( p.product_id = oi.product_id )
WHERE p.product_category_name IS NOT NULL
3.3.2 FIRST_VALUE()
Retorna o menor valor dentro da segmentação da janela
Exemplo:
SELECT
p.product_category_name,
oi.price,
oi.shipping_limit_date,
FIRST_VALUE( oi.shipping_limit_date ) OVER ( PARTITION BY p.product_category_name ORDER BY oi.shipping_limit_date DES
Windows Function - Parte III 3
Conteúdo licenciado para -
FROM order_items oi INNER JOIN products p ON ( p.product_id = oi.product_id )
WHERE p.product_category_name IS NOT NULL
3. Controle do tamanho da janela
4.1 PRECEDING, CURRENT, FOLLOWING
A função PRECEDING, considera X linhas antes da linha atual.
A função CURRENT, considera até a linha atual.
A função FOLLOWING, considera X linhas depois da atual
Exemplo:
-- Calcular a média móvel do preco, considerando os últimos
-- 3 dias até o momento atual.
SELECT
o.order_purchase_timestamp,
oi.price,
AVG( oi.price ) OVER ( ORDER BY o.order_purchase_timestamp
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW ) AS media_movel
FROM orders o LEFT JOIN order_items oi ON ( oi.order_id = o.order_id )
-- Calcular a média móvel do preco, considerando os últimos
-- 3 dias até o dia de amanhã.
SELECT
o.order_purchase_timestamp,
oi.price,
AVG( oi.price ) OVER ( ORDER BY o.order_purchase_timestamp
ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING ) AS media_movel
FROM orders o LEFT JOIN order_items oi ON ( oi.order_id = o.order_id )
4.2 UNBOUNDED PRECEDING, UNBOUNDED FOLLOWING
A função UNBOUNDED PRECEDING não considera limites para o início antes da linha atual, enquanto que a função
UNBOUNDED FOLLOWING não considera limite para o fim depois da linha atual.
Exemplo:
-- Calcular a média móvel do preco, considerando o
-- passado histórico
SELECT
o.order_purchase_timestamp,
oi.price,
AVG( oi.price ) OVER ( ORDER BY o.order_purchase_timestamp
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS media_movel
FROM orders o LEFT JOIN order_items oi ON ( oi.order_id = o.order_id )
SELECT
o.order_purchase_timestamp,
oi.price,
AVG( oi.price ) OVER ( ORDER BY o.order_purchase_timestamp
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING ) AS media_movel
FROM orders o LEFT JOIN order_items oi ON ( oi.order_id = o.order_id )
4. Exercícios
4.1 Cria uma consulta que liste a categoria, o preço do produto e classificação de cada produto dentro da sua categoria
do mais caro ao mais barato, a partir do dia 01 de Junho de 2018.
4.1.1 Resolução
SELECT
categoria,
product_id,
preco,
DENSE_RANK() OVER ( PARTITION BY categoria ORDER BY preco DESC ) AS classificacao
FROM (
SELECT
p.product_id,
p.product_category_name AS categoria,
AVG( oi.price ) AS preco
Windows Function - Parte III 4
Conteúdo licenciado para -
FROM orders o LEFT JOIN order_items oi ON ( oi.order_id = o.order_id )
LEFT JOIN products p ON ( p.product_id = oi.product_id )
LEFT JOIN order_reviews or2 ON ( or2.order_id = o.order_id )
WHERE o.order_purchase_timestamp > '2018-06-01 00:00:00'
GROUP BY p.product_id
HAVING p.product_category_name IS NOT NULL
)
4.2 Crie uma consulta que exiba a data de compra, o valor de cada venda e o total acumulado de vendas até aquela
data.
4.2.1 Resolução
SELECT
o.order_purchase_timestamp,
oi.price,
SUM( oi.price ) OVER ( ORDER BY o.order_purchase_timestamp ) AS total_acumulado
FROM orders o LEFT JOIN order_items oi ON ( oi.order_id = o.order_id )
4.3 Crie uma consulta que exiba a data de compra, o valor de cada venda e a média móvel dos últimos três valores de
venda incluindo o valor atual
4.3.1 Resolução
SELECT
o.order_purchase_timestamp,
oi.price,
AVG( oi.price ) OVER ( ORDER BY o.order_purchase_timestamp
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW ) AS media_movel
FROM orders o LEFT JOIN order_items oi ON ( oi.order_id = o.order_id )
4.4 Crie uma consulta que lista a data da compra, o número de produtos vendidos e o crescimento das vendas com
relação ao dia anterior.
4.4.1 Resolução
SELECT
data_venda,
vendas,
vendas - LAG( vendas ) OVER ( ORDER BY data_venda ) AS growth
FROM (
SELECT
o.order_purchase_timestamp AS data_venda,
COUNT( p.product_id ) AS vendas
FROM orders o LEFT JOIN order_items oi ON ( oi.order_id = o.order_id )
LEFT JOIN products p ON ( p.product_id = oi.product_id )
GROUP BY o.order_purchase_timestamp
ORDER BY o.order_purchase_timestamp ASC
)
4.5 Crie uma consulta que exiba o estado do cliente, a categoria, a quantidade de produtos vendidos e o percentual de
vendas em relação ao total vendido no estado.
4.5.1 Resolução
SELECT
state,
categoria,
produtos,
SUM( produtos) OVER ( PARTITION BY state ) AS total_categoria,
produtos*1.0 / SUM( produtos) OVER ( PARTITION BY state ) AS percentual_vendas
FROM (
SELECT
c.customer_state AS state,
p.product_category_name AS categoria,
COUNT( oi.product_id ) AS produtos
FROM orders o LEFT JOIN order_items oi ON ( oi.order_id = o.order_id )
LEFT JOIN products p ON ( p.product_id = oi.product_id )
LEFT JOIN customer c ON ( c.customer_id = o.customer_id )
WHERE p.product_category_name IN ( 'beleza_saude', 'brinquedos')
GROUP BY c.customer_state, p.product_category_name
HAVING p.product_category_name IS NOT NULL
)
Windows Function - Parte III 5
Conteúdo licenciado para -
5. Próxima aula
Funções de manipulação de colunas
Windows Function - Parte III 6
Conteúdo licenciado para -