Criando um ranking com SQL

Criando um ranking com SQL

Neste artigo você aprenderá como extrair qualquer posição de um ranking utilizando SQL.

O exemplo que será utilizado neste artigo é uma tabela de funcionários e seus respectivos salários. Vamos criar uma tabela para guardar as informações que vamos utilizar neste exemplo.

//SQL Server

CREATE TABLE funcionarios

(

id INT IDENTITY(1,1) PRIMARY KEY,

nome VARCHAR(150),

salario Numeric( 18,2 )

);

//MySQL

CREATE TABLE funcionarios (

id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,

nome VARCHAR(150) NOT NULL,

salario DECIMAL(18, 2)

)

Agora vamos inserir alguns registros de testes:

INSERT INTO funcionarios (nome, salario) VALUES ('João', 2000 );

INSERT INTO funcionarios (nome, salario) VALUES ('Lucas', 2500 );

INSERT INTO funcionarios (nome, salario) VALUES ('Matheus', 3000 );

INSERT INTO funcionarios (nome, salario) VALUES ('Thiago', 3500 );

INSERT INTO funcionarios (nome, salario) VALUES ('Paulo', 3500 );

INSERT INTO funcionarios (nome, salario) VALUES ('Simão', 4500 );

Se você quiser saber qual é o maior salário, pode utilizar a função MAX, e se deseja saber qual é o menor salário, pode utilizar a função MIN

SELECT MAX(salario) as maior_salario FROM funcionarios

SELECT MIN(salario) as menor_salario FROM funcionarios

O que desejamos saber não é apenas o maior e o menor valor, mas saber quem é o funcionário. 

Os exemplos a seguir vão utilizar o SQL Server

Vamos utilizar a função ROW_NUMBER() para numerar os resultados e informar que a ordenação é com base no campo salário, este campos será ordenado por ordem decrescente de salário, para trazer primeiro os maiores valores. Para saber quem ganha o maior salário,  basta fazer desta forma:

SELECT id, nome, salario

FROM

(

Select id, nome, salario, ROW_NUMBER() OVER(Order by salario DESC) as ordem

from   funcionarios

) DT

WHERE DT.ordem = 1 ;

Perceba que neste exemplo fizemos uma consulta para criar o campo ordem, e depois, sobre esta consulta, fizemos uma segunda consulta para poder utilizar o campo que foi criado na primeira consulta (o campo "ordem"), tomando este campo como referência, filtramos pelo registro que tem o campo "ordem" com o valor 1. Como os registros foram ordenados por ordem de salário, vamos ter como resposta o registro (ou registros) que possuem o maior salário.

Se você quiser saber quem tem o segudo maior salário, bastaria fazer o seguinte:

SELECT id, nome, salario

FROM

(

Select id, nome, salario, ROW_NUMBER() OVER(Order by salario DESC) as ordem

from   funcionarios

) DT

WHERE DT.ordem = 2 ;

E se for necessário saber quem tem o menor salário? Para resolver este problema, vamos mudar o critério de ordenação utilizado para criar o campo ordem

SELECT id, nome, salario

FROM

(

Select id, nome, salario, ROW_NUMBER() OVER(Order by salario) as ordem

from   funcionarios

) DT

WHERE DT.ordem = 1 ;

Outro recurso muito útil na hora de criar rankings é verificar quais os maiores valores repetidos. Perceba que em nosso exemplo, o valor 3500 é o segundo maior salário, e este valor é compartilhado por dois funcionários. Quando executamos a nossa consulta para ver quem ocupava o segundo lugar, o resultado foi apenas 1 registro. Isso porque a função ROW_NUMBER aplica um número único para cada registro.

Para resolver este novo problema, vamos substituir ROW_NUMBER e utilizar a função DENSE_RANK 

SELECT id, nome, salario

FROM

(

Select id, nome, salario, DENSE_RANK() OVER(Order by salario DESC) as ordem

from   funcionarios

) DT

WHERE DT.ordem = 2 ;

Desta forma, ao pesquisar pelo segundo maior salário, vamos ter como resultado dois funcionários, que é o resultado que estavamos esperando.

Como nossa tabela de testes tem apenas 6 registros, foi fácil saber qual era a posição que tinha os valores repetidos. Caso você queira saber quais as posições que tem valores repetidos, será necessário agrupar os resultados.

SELECT ordem

FROM

(

Select id, nome, salario, DENSE_RANK() OVER(Order by salario DESC) as ordem

from   funcionarios

) DT

group by ordem having count(*) > 1

order by ordem

Caso você utilize o MySQL, estas funções existem nas versões superiores a 8. Se a sua versão é inferior a versão 8, pode chegar no mesmo resultado utilizando as consultas a seguir.

Para row_number():

SELECT id, nome, salario, ordem from (

Select id, nome, salario, (@row_number:=@row_number + 1) as ordem

from   funcionarios,  (SELECT @row_number:=0) AS t

order by salario DESC

) DT

WHERE ordem = 1

Para dense_rank():

SELECT id, nome, salario, ordem from(

SELECT id, nome, salario, 

CASE 

WHEN @prevRank = salario THEN @curRank 

WHEN @prevRank := salario THEN @curRank := @curRank + 1

END AS ordem

FROM funcionarios F, 

(SELECT @curRank :=0, @prevRank := NULL) r

ORDER BY salario DESC

) A WHERE ordem = 2

 

Outros conteudos que podem ser de seu interesse

SQL vs Mongo - consultas com agrupamento
15/12/2019SQL

SQL vs Mongo - consultas com agrupamento

Veja exemplos de consultas com agrupamento no SQL e seus equivalentes no Mongo

Saiba mais...
Funções do Excel que você precisa conhecer
31/03/2026SQL

Funções do Excel que você precisa conhecer

Conheça as funções do Excel mais utilizadas

Saiba mais...
Como agrupar vários registros em uma única coluna com SQL
26/06/2022SQL

Como agrupar vários registros em uma única coluna com SQL

Veja como agrupar várias linhas em uma única coluna com SQL

Saiba mais...

Conteúdo sobre banco de dados sem complicação!


Warning: Cannot modify header information - headers already sent by (output started at /home/storage/f/7d/a9/dbins/public_html/blog/post.php:101) in /home/storage/f/7d/a9/dbins/public_html/blog/ga4_track.php on line 11