Considerando isoladamente a extração de dados OVER é uma o mais interessante recurso incluído ao Firebird.
Há uma possibilidade grande de combinações onde OVER se aplica – não vamos conseguir cobrir tudo somente neste POST, então vamos nos concentrar a um texto já tratando neste blog em relação a versão 2.5, que é apresentação de RANK, ou seja, mostrar a posição que se encontra o dado dentro da lista..
Ex: Qual a posição do vendedor XXX no RANK de vendas;
A implementação segue um padrão de estrutura tratado como “analytical functions”, ou seja, funções analíticas ou de análise de dados.
A ideia é usar um SELECT para separar uma janela de dados em paralelo do mesmo dado e montar um relacionamento dos dados do SELECT com os dados da JANELA para efetuar algum cálculo… no caso, calcular o RANK.
Tomando o exemplo da documentação emprestado
[code language=”sql”]select id, salary,
dense_rank() over (order by salary),
rank() over (order by salary),
row_number() over (order by salary),
sum(1) over (order by salary)
from employee
order by salary;
The result set:
id salary dense_rank rank row_number sum
— —— ———- —- ———- —
3 8.00 1 1 1 1
4 9.00 2 2 2 2
1 10.00 3 3 3 4
5 10.00 3 3 4 4
2 12.00 4 5 5 5
[/code]
Fazendo uma leitura do exemplo, em primeiro passo o engine monta o SELECT – quando encontra o comando OVER, ele separa uma janela em paralelo com os dados do mesmo SELECT (agora tem 1 cópia do mesmo dado do SELECT)… o que vem depois do OVER (….) é a forma em que o dado será organizado – no exemplo ORDER BY Salary; Sobre a janela de dados aplica a função indicada – o RANK();
Pegando carona no exemplo:
Há uma diferença entre RANK() e DENSE_RANK(), em relação a forma de sequencia montada quando existe repetição do dado… enquanto RANK() continua a contagem quando encontra repetições, no DENSE_RANK() o número é mantido e segue a mesma sequencia do número anterior.
ROW_NUMBER() é uma contagem simples de linhas sem diferenciar dados repetidos como faz o RANK();