CodeGym /Cursos /SQL SELF /Sintaxe do OVER() e suas principais particularidades

Sintaxe do OVER() e suas principais particularidades

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

OVER() é uma instrução que diz pro SQL sobre qual conjunto de linhas a função window deve ser aplicada. Dá pra dizer que é um jeito de definir a "janela" de dados pra usar a função window. Imagina que a gente tem uma sala cheia de pessoas e quer contar quantas pessoas estão em cada metro quadrado do chão. O OVER() vai mostrar em qual parte da sala a gente vai focar. Em outras palavras, ele define sobre qual conjunto de linhas a função vai trabalhar.

O operador OVER() é usado só com funções window pra fazer operações sobre linhas de uma ou mais tabelas, sem agrupar os dados.

Sintaxe:

funcao_window() OVER (
    [PARTITION BY ...]
    [ORDER BY ...]
    [ROWS/RANGE ...]
)

Onde:

  • PARTITION BY — divide o conjunto de dados em grupos lógicos
  • ORDER BY — define a ordem das linhas dentro de cada grupo
  • ROWS/RANGE — especifica o tamanho da "janela" (tipo, linha atual + 1 próxima)

Exemplo: OVER() sem parâmetros

Quando OVER() é usado sem parâmetros extras, isso quer dizer que a função antes dele vai rodar sobre todo o conjunto de dados.

SELECT
    employee_id,
    salary,
    ROW_NUMBER() OVER () AS row_num -- ROW_NUMBER() vai ser aplicada pra todas as linhas do resultado
FROM employees;

O que rola aqui?

  1. ROW_NUMBER() dá um número único pra cada linha.
  2. Como não tem parâmetro no OVER(), todas as linhas da tabela employees são tratadas como um bloco só.

Resultado:

employee_id salary row_num
1 50000 1
2 60000 2
3 55000 3

Usando PARTITION BY pra definir grupos

Show, agora imagina que a gente quer numerar os funcionários não na empresa toda, mas dentro de cada departamento. É aí que entra o PARTITION BY.

PARTITION BY dentro do OVER() divide os dados em grupos (ou "partições"). Pra cada grupo, a função calcula o valor separado. Tipo, se o ROW_NUMBER() fosse um garçom, ele começaria a contar de novo pra cada "mesa" (partição).

Exemplo: usando PARTITION BY

SELECT
    department_id,
    employee_id,
    salary,
    ROW_NUMBER() OVER (PARTITION BY department_id) AS row_num
FROM employees;

O que rola aqui?

  1. Os dados da tabela employees são divididos em grupos pelo valor de department_id.
  2. Em cada grupo, as linhas recebem um número de ordem pelo ROW_NUMBER().

Resultado:

department_id employee_id salary row_num
1 1 50000 1
1 3 55000 2
2 2 60000 1

Usando ORDER BY pra definir a ordem

Agora bora colocar um pouco de ordem na parada. Imagina que a gente quer numerar as linhas, mas começando pelo maior salário. Isso dá pra fazer com o ORDER BY.

ORDER BY define a ordem em que as linhas vão ser processadas pela função window.

Exemplo: usando ORDER BY dentro do OVER()

SELECT
    department_id,
    employee_id,
    salary,
    RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank
FROM employees;

O que rola aqui?

  1. Os dados são divididos em grupos (PARTITION BY department_id).
  2. Dentro de cada grupo, as linhas são ordenadas do maior pro menor salário (ORDER BY salary DESC).
  3. Cada linha recebe um rank de acordo com a ordem.

Resultado:

department_id employee_id salary rank
1 3 55000 1
1 1 50000 2
2 2 60000 1

Combinando funções window

SQL deixa usar várias funções window numa mesma query, e cada uma pode rodar com suas próprias regras. É tipo numa sala onde tá rolando música e alguém tá contando pessoas ao mesmo tempo — cada coisa é independente!

Exemplo: várias funções window

SELECT
    department_id,
    employee_id,
    salary,
    ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS row_num,
    AVG(salary) OVER (PARTITION BY department_id) AS avg_salary
FROM employees;

O que rola aqui?

  1. ROW_NUMBER() numera as linhas em cada grupo do maior pro menor salário.
  2. AVG() calcula o salário médio em cada grupo.

Resultado:

department_id employee_id salary row_num avg_salary
1 3 55000 1 52500
1 1 50000 2 52500
2 2 60000 1 60000

Exemplos do mundo real

Funções window com OVER() são usadas em vários cenários reais. Olha só alguns exemplos:

  • Análise de vendas: ranquear produtos pelo número de vendas em cada categoria.
  • Rankings: descobrir a posição dos alunos em cada turma pela média de notas.
  • Séries temporais: soma acumulada de vendas ao longo do tempo.

Exemplo de análise de vendas:

SELECT
    category_id,
    product_id,
    product_name,
    SUM(sales) OVER (PARTITION BY category_id ORDER BY sales DESC) AS cumulative_sales
FROM products;

Erros comuns ao usar funções window

  1. Faltou o PARTITION BY

Se você não usar o PARTITION BY, a função window vai rodar na tabela toda. Isso pode dar resultado estranho, principalmente se você esperava dividir por grupos.

💡 Confere se você deixou claro como a tabela deve ser dividida — tipo por usuário, pedido ou categoria.


  1. Tipos de dados errados no ORDER BY

ORDER BY dentro da função window liga muito pra tipo de dado. Se você ordenar por um campo de data que tá como texto (VARCHAR), a ordem pode sair alfabética, não cronológica.

💡 Converte esses campos pro tipo certo (DATE, INTEGER etc) antes de ordenar.

  1. Uso errado do ROWS BETWEEN

Por padrão, funções window trabalham com limites definidos pelo ROWS BETWEEN. Se você não definir o limite, pode ser que o RANGE seja usado, e ele pode trazer mais linhas do que você queria.

💡 Pra controlar direitinho, usa ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW se quiser um acumulado do começo até a linha atual.

  1. Trabalhando errado com NULL

Funções window podem tratar NULL de jeitos diferentes. Por exemplo, RANK() e DENSE_RANK() vão considerar NULL como valor e dar um rank separado pra ele.

💡 Usa NULLS LAST ou NULLS FIRST no ORDER BY se for importante onde o NULL deve ficar.

  1. Usar funções window agregadas quando não precisa

Às vezes a galera usa funções window agregadas (SUM() OVER(...)) quando dava pra usar agregação normal com GROUP BY, o que deixa a query mais pesada e lenta.

💡 Só usa funções window quando você realmente precisa manter o detalhe linha a linha.

2
Tarefa
SQL SELF, nível 29, lição 2
Bloqueado
Numeração de linhas na tabela
Numeração de linhas na tabela
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION