CodeGym /Cursos /SQL SELF /Usando PARTITION BY pra dividir dados em gr...

Usando PARTITION BY pra dividir dados em grupos

SQL SELF
Nível 29, Lição 3
Disponível

Imagina que tu trabalha como garçom (ou barista, se tu curte café) num restaurante grandão. Todo dia tu faz a soma das gorjetas que ganhou. Mas tem um detalhe: o restaurante é dividido em áreas, e tu quer saber quanto de gorjeta rolou em cada área separada. PARTITION BY é tipo o que o SQL usa pra "dividir o restaurante em áreas".

Falando mais formalmente, PARTITION BY é usado nas funções window pra separar todas as linhas da tabela em grupos (ou "partições"). Dentro de cada grupo, a função window roda de novo. É como se tu aplicasse a função separadamente em cada "partição".

Exemplo: como isso funciona

Vamos supor que a gente tem uma tabela sales com dados de vendas:

region salesperson amount
North Alice 100
North Bob 200
South Alice 150
South Charlie 250

Se a gente quiser calcular quanto cada vendedor faturou, mas separado por região, PARTITION BY é o que a gente precisa.

Sintaxe do PARTITION BY

A sintaxe é bem de boa:

funcao_window() OVER (PARTITION BY coluna_ou_colunas)
  • funcao_window() — tipo SUM(), AVG(), ROW_NUMBER() e por aí vai.
  • PARTITION BY coluna — diz por qual coluna tu vai separar as linhas.
  • OVER() — é o operador que fala pro SQL: "Faz isso dentro da janela que eu tô dizendo".

Exemplo: soma por grupos

Bora calcular o total de vendas pra cada região:

SELECT
    region,
    salesperson,
    amount,
    SUM(amount) OVER (PARTITION BY region) AS total_sales_by_region
FROM sales;

O resultado vai ser assim:

region salesperson amount total_sales_by_region
North Alice 100 300
North Bob 200 300
South Alice 150 400
South Charlie 250 400

O que tá rolando aqui? O SQL separa as linhas em grupos pelo valor da coluna region (North e South), aí aplica a função SUM() separada pra cada grupo. No fim, as linhas do grupo "North" pegam o mesmo valor de soma, e as do grupo "South" outro valor.

Exemplos de uso do PARTITION BY

Bora ver como PARTITION BY pode ser útil em situações da vida real.

Exemplo 1: Ranking dentro do grupo

Imagina que a gente quer ranquear os vendedores dentro de cada região pelo valor das vendas. Pra isso, dá pra usar PARTITION BY junto com a função RANK():

SELECT
    region,
    salesperson,
    amount,
    RANK() OVER (PARTITION BY region ORDER BY amount DESC) AS rank_in_region
FROM sales;

Resultado:

region salesperson amount rank_in_region
North Bob 200 1
North Alice 100 2
South Charlie 250 1
South Alice 150 2

A função RANK() dá um ranking dentro de cada grupo region, começando do 1. Saca que pra cada grupo o ranking começa do um.

Exemplo 2: Comparando cada valor com a média do grupo

Vamos supor que a gente quer ver quanto cada vendedor faturou comparado com a média da região dele. Bora usar AVG():

SELECT
    region,
    salesperson,
    amount,
    AVG(amount) OVER (PARTITION BY region) AS avg_sales_by_region,
    amount - AVG(amount) OVER (PARTITION BY region) AS diff_from_avg
FROM sales;

Resultado:

region salesperson amount avg_sales_by_region diff_from_avg
North Alice 100 150 -50
North Bob 200 150 50
South Alice 150 200 -50
South Charlie 250 200 50

Primeiro o SQL separa as linhas em grupos por region. Depois calcula a média AVG(amount) pra cada grupo. Por fim, pra cada linha, calcula a diferença entre o valor dela e a média.

Exemplo 3: Numerando linhas dentro do grupo

Digamos que tu quer numerar todas as transações dentro de cada grupo de região. Bora usar ROW_NUMBER():

SELECT
    region,
    salesperson,
    amount,
    ROW_NUMBER() OVER (PARTITION BY region ORDER BY amount DESC) AS row_number
FROM sales;

Resultado:

region salesperson amount row_number
North Bob 200 1
North Alice 100 2
South Charlie 250 1
South Alice 150 2

Comparando com GROUP BY

Direto rola confusão entre PARTITION BY e GROUP BY. Bora comparar eles:

GROUP BY

GROUP BY muda a estrutura do resultado — ele transforma as linhas da tabela em agregados. Tipo assim:

SELECT
    region,
    SUM(amount) AS total_sales
FROM sales
GROUP BY region;

Resultado:

region total_sales
North 300
South 400

Aqui a gente perde a info dos vendedores, porque os dados são agregados.

PARTITION BY

PARTITION BY, ao contrário, não muda a estrutura. A gente ainda vê cada linha, mas agora tem valores extras calculados por grupo. Ou seja, PARTITION BY deixa tu agregar sem perder os detalhes.

Erros comuns usando PARTITION BY

Erro 1: Esqueceu o PARTITION BY

Às vezes tu quer agrupar os dados, mas esquece de usar o PARTITION BY. Tipo assim:

SELECT
    region,
    salesperson,
    amount,
    SUM(amount) OVER () AS total_sales
FROM sales;

Resultado:

region salesperson amount total_sales
North Alice 100 700
North Bob 200 700
South Alice 150 700
South Charlie 250 700

Aqui o SUM(amount) foi calculado pra tabela toda, não separado por região. Se tu quiser considerar as regiões, não esquece de botar PARTITION BY region.

Erro 2: Ordem errada no ORDER BY

A ordem das linhas dentro da janela é importante pra funções tipo RANK() ou ROW_NUMBER(). Fica ligado quando usar ORDER BY dentro do OVER().

2
Tarefa
SQL SELF, nível 29, lição 3
Bloqueado
Soma de vendas por região
Soma de vendas por região
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION