OlĂ¡ leitores,
Bom dia!
Recentemente tive uma necessidade de criar um ranking no MySQL semelhante ao ROW_NUMBER() do SQL Server. Infelizmente, a Oracle ainda nĂ£o implementou esse recurso tĂ£o Ăºtil, mas como se tudo dĂ¡ um jeito, vou mostrar a vocĂªs como podemos implementar isso.
Uma forma bem simples de fazer isso, Ă© criar uma tabela e incluir um campo de auto incremento, como o exemplo abaixo:
1 2 3 4 5 6 7 8 |
DROP TABLE IF EXISTS `teste`; CREATE TABLE `teste`( `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, `nome` VARCHAR(50) NOT NULL, `idade` INT(11) UNSIGNED NOT NULL, PRIMARY KEY (`id`) ); |
Dessa forma, cada linha terĂ¡ o seu prĂ³prio ID incremental, que pode ser usado como Ranking.
O problema Ă© quando precisamos criar queries um pouco mais complexas utilizando com joins e filtros e precisamos criar um ranking nessa query. Podemos criar uma tabela e guardar o resultado dessa query na tabela usando um auto incremento?
Sim, mas Ă© um opĂ§Ă£o bem trabalhosa, principalmente se muitas colunas forem retornadas na query.
Populando dados de forma que a nossa tabela fique conforme a estrutura abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
id nome idade ------ ---------------- -------- 1 JoĂ£o Zebedeu 27 2 Pedro 32 3 Mateus 15 4 Judas Tadeu 29 5 AndrĂ© 64 6 TomĂ© 60 7 Filipe 25 8 Bartolomeu 47 9 Tiago 28 10 Tiago 33 11 Judas Iscariotes 666 12 SimĂ£o 39 |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
INSERT INTO `teste` (nome, idade) VALUES('JoĂ£o Zebedeu', 27), ('Pedro', 32), ('Mateus', 15), ('Judas Tadeu', 29), ('AndrĂ©', 64), ('TomĂ©', 60), ('Filipe', 25), ('Bartolomeu', 47), ('Tiago', 28), ('Tiago', 33), ('Judas Iscariotes', 666), ('SimĂ£o', 39); |
Podemos atender a nossa necessidade criando a query da seguinte forma:
1 2 3 4 5 6 7 8 9 10 |
SELECT id, nome, idade, @curRank := @curRank + 1 AS rank FROM teste p, (SELECT @curRank := 0) r ORDER BY idade; |
E esse Ă© o retorno:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
id nome idade rank ------ ---------------- ------ -------- 3 Mateus 15 1 7 Filipe 25 2 1 JoĂ£o Zebedeu 27 3 9 Tiago 28 4 4 Judas Tadeu 29 5 2 Pedro 32 6 10 Tiago 33 7 12 SimĂ£o 39 8 8 Bartolomeu 47 9 6 TomĂ© 60 10 5 AndrĂ© 64 11 11 Judas Iscariotes 666 12 |
Exatamente o que eu precisava!
AtĂ© a prĂ³xima!
Bom dia Dirceu!
Muito bom o post, funcionou direitinho. Contudo o problema Ă© que nĂ£o Ă© possĂvel filtrar os resultados pela coluna rank na clĂ¡usula WHERE, pois resulta como coluna desconhecida.
Exemplo:
SELECT
id,
nome,
idade,
@curRank := @curRank + 1 AS rank
FROM
teste p,
(SELECT @curRank := 0) r
ORDER BY
idade
WHERE
rank BETWEEN 1 AND 5 || nome=’Bartolomeu’
Resulta em erro do tipo “#1054 – Unknown column ‘rank’ in ‘where clause'”
Abraços!!
Danilo,
Boa noite!
Primeiramente, obrigado pela visita!
Para filtrar utilizando o Ranking que vocĂª criou, pode-se utilizar subqueries:
SELECT *
FROM (
SELECT
id,
nome,
idade,
@curRank := @curRank + 1 AS rank
FROM
teste p,
(SELECT @curRank := 0) r
ORDER BY
idade
) A
WHERE
A.rank >= 5