Na aula passada, a gente entendeu pra que servem as funções de janela. Agora bora ver funções específicas e o que elas retornam. Os detalhes de sintaxe a gente vê na próxima aula.
Função ROW_NUMBER()
A função ROW_NUMBER() retorna um número único pra cada linha dentro da janela. É basicamente uma numeração das linhas na ordem que você definiu no ORDER BY.
Sintaxe:
ROW_NUMBER() OVER ([PARTITION BY coluna] ORDER BY coluna)
Onde:
PARTITION BY coluna(opcional): divide os dados em grupos. Se não usar, a numeração vai ser global pra todo o conjunto.ORDER BY coluna: define a ordem das linhas pra numerar.
Exemplo. Numerando linhas na tabela
Bora olhar a tabela students, que tem info dos estudantes e suas notas.
SELECT * FROM students;
| id | name | score |
|---|---|---|
| 1 | Eva Lang | 95 |
| 2 | Maria Chi | 87 |
| 3 | Alex Lin | 78 |
| 4 | Anna Song | 95 |
| 5 | Otto Mart | 87 |
Agora bora numerar as linhas em ordem decrescente das notas (score):
SELECT
name,
score,
ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num
FROM students;
Resultado:
| name | score | row_num |
|---|---|---|
| Eva Lang | 95 | 1 |
| Anna Song | 95 | 2 |
| Maria Chi | 87 | 3 |
| Otto Mart | 87 | 4 |
| Alex Lin | 78 | 5 |
Cada linha ganhou um número único — levando em conta a ordenação decrescente das notas.
É uma operação simples, mas poderosa — adicionar o número da linha no resultado do select. No SELECT clássico, não dá pra fazer isso sem funções de janela.
Função RANK()
A função RANK() é bem parecida com a ROW_NUMBER(), mas ela leva em conta valores iguais. Se as linhas tiverem o mesmo valor na ordenação, elas recebem o mesmo rank, e o próximo rank é pulado.
Sintaxe:
RANK() OVER ([PARTITION BY coluna] ORDER BY coluna)
Exemplo. Ranqueando estudantes pelas notas
Bora usar RANK() com os mesmos dados:
SELECT
name,
score,
RANK() OVER (ORDER BY score DESC) AS rank
FROM students;
Resultado:
| name | score | rank |
|---|---|---|
| Eva Lang | 95 | 1 |
| Anna Song | 95 | 1 |
| Maria Chi | 87 | 3 |
| Otto Mart | 87 | 3 |
| Alex Lin | 78 | 5 |
Aqui, linhas com valores iguais (95 e 87) receberam o mesmo rank, e os ranks seguintes foram pulados.
Função DENSE_RANK()
DENSE_RANK() é parecida com RANK(), mas não pula valores de rank. Ou seja, se tem linhas repetidas, o próximo rank vai ser só um a mais que o anterior.
Sintaxe:
DENSE_RANK() OVER ([PARTITION BY coluna] ORDER BY coluna)
Exemplo. Ranqueamento denso
Vamos usar DENSE_RANK() com os mesmos dados:
SELECT
name,
score,
DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank
FROM students;
Resultado:
| name | score | dense_rank |
|---|---|---|
| Eva Lang | 95 | 1 |
| Anna Song | 95 | 1 |
| Maria Chi | 87 | 2 |
| Otto Mart | 87 | 2 |
| Alex Lin | 78 | 3 |
Aqui, diferente do RANK(), os valores dos ranks só aumentam, sem pular nenhum número.
Função NTILE()
A função NTILE() divide as linhas em grupos iguais (quantis) e dá pra cada linha o número do grupo.
Sintaxe:
NTILE(n) OVER ([PARTITION BY coluna] ORDER BY coluna)
n: quantidade de grupos que você quer dividir os dados.
Exemplo. Dividindo estudantes em 3 grupos
Bora dividir os estudantes em 3 grupos pela ordem decrescente das notas:
SELECT
name,
score,
NTILE(3) OVER (ORDER BY score DESC) AS group_num
FROM students;
Resultado:
| name | score | group_num |
|---|---|---|
| Eva Lang | 95 | 1 |
| Anna Song | 95 | 1 |
| Maria Chi | 87 | 2 |
| Otto Mart | 87 | 2 |
| Alex Lin | 78 | 3 |
Repara: se não der pra dividir as linhas em grupos exatamente iguais, as linhas "sobrando" vão pros primeiros grupos. Nesse exemplo, os dois primeiros grupos têm duas linhas cada, e o último só uma.
Quando usar cada função?
ROW_NUMBER(): pra numerar as linhas de forma única na ordem da ordenação.RANK(): pra ranquear levando em conta valores iguais e pulando o próximo rank.DENSE_RANK(): pra ranquear levando em conta valores iguais, mas sem pular ranks.NTILE(): Pra dividir as linhas em grupos iguais.
Todas essas funções ajudam a analisar dados de um jeito muito mais flexível. Usa elas quando precisar calcular números de ordem ou dividir dados em grupos de forma mais esperta.
GO TO FULL VERSION