20th Jul 2022 7 minutos de leitura Visão geral das funções de classificação em SQL Dorota Wdzięczna sql aprender sql rank Índice ROW_NUMBER() Exemplo 1 Exemplo 2 RANK() Exemplo 1 Exemplo 2 DENSE_RANK() Exemplo 1 Exemplo 2 PERCENT_RANK() Exemplo 1 Exemplo 2 Resumo As funções de ranking SQL facilitam o trabalho com bancos de dados relacionais, especialmente para analistas de dados, marqueteiros e especialistas financeiros. Estas funções são usadas para atribuir um número de ranking para cada registro e permitem criar relatórios úteis de forma eficiente. As funções de ranking SQL são funções de janela. As funções de janela calculam o resultado com base em um conjunto de linhas. A palavra "janela" se refere a este conjunto de linhas. Vejamos a sintaxe das funções de ranking: rank_function OVER ( [PARTITION BY partition_expression, ... ] ORDER BY order_expression [ASC | DESC] ... ) A sintaxe começa com o nome da função de ranking, como RANK(), DENSE_RANK(), ROW_NUMBER(), ou PERCENT_RANK(), e a cláusula OVER(). Na cláusula OVER(), você especifica as cláusulas PARTITION BY e ORDER BY. Para funções de ranking, a cláusula ORDER BY, incluindo o(s) nome(s) da(s) coluna(s) ou uma expressão, é obrigatória. Antes da cláusula ORDER BY está a cláusula opcional PARTITION BY, que inclui o(s) nome(s) da(s) coluna(s) ou uma expressão. A cláusula PARTITION BY divide o conjunto de linhas em grupos de filas para classificações separadas. Não se preocupe se esta sintaxe parecer complicada. Explicarei passo a passo nas seções seguintes. Os exemplos nas seções seguintes utilizarão a tabela saleque armazena dados nas colunas salesman_id, sale_date, e sale_amount. Veja a tabela de venda abaixo: salesman_idsale_datesale_amount 112020-04-2012500.00 122020-04-2012500.00 132020-04-2211000.00 112020-04-2211000.00 122020-04-2222800.00 122020-04-219500.00 112020-04-2131000.00 ROW_NUMBER() A primeira função de ranking que discutirei é ROW_NUMBER(). Ela retorna o número seqüencial de cada registro no conjunto de resultados ou dentro da partição do conjunto de resultados, começando com 1. Usando ROW_NUMBER(), você pode selecionar todos os registros e numerá-los. Veja o Exemplo 1 abaixo. Exemplo 1 SELECT ROW_NUMBER() OVER(ORDER BY sale_amount) AS row_number, sale_date, salesman_id, sale_amount FROM sale; Esta consulta retorna o resultado: row_numbersale_datesalesman_idsale_amount 12020-04-21129500.00 22020-04-221311000.00 32020-04-221111000.00 42020-04-201112500.00 62020-04-201212500.00 72020-04-221222800.00 82020-04-211131000.00 Neste caso, a cláusula OVER contém apenas a cláusula ORDER BY com a coluna sale_amount (esta cláusula ordena as linhas de acordo com o valor da venda ascendendo de $9.500 a $31.000). A consulta retorna o número seqüencial a partir de 1 na coluna row_number. Observe que as linhas que têm o mesmo valor na coluna sale_amount recebem números diferentes. Portanto, se você quiser classificar todos os registros com um número único, use ROW_NUMBER(). E se você gostaria de numerar grupos separados de linhas? Você pode usar a cláusula opcional PARTITION BY antes da cláusula ORDER BY. Veja o Exemplo 2 abaixo. Exemplo 2 SELECT ROW_NUMBER() OVER(PARTITION BY sale_date ORDER BY sale_amount) AS row_number, sale_date, salesman_id, sale_amount FROM sale; Os registros são divididos em grupos (chamados de "partições") pela data de venda. Dentro de cada partição, os registros são numerados separadamente. Esta consulta retorna o resultado: row_numbersale_datesalesman_idsale_amount 12020-04-201212500.00 22020-04-201112500.00 12020-04-21129500.00 22020-04-211131000.00 12020-04-221111000.00 22020-04-221311000.00 32020-04-221222800.00 Para a data de venda 2020-04-20, as linhas têm os números 1 e 2, mesmo que os valores do valor da venda sejam os mesmos. Na partição seguinte, a linha com o menor valor de venda tem o número 1, e a linha com o maior valor de venda tem o número 2. Os registros dentro de cada partição são ordenados de acordo com a coluna em ORDER BY. RANK() A segunda função do ranking é RANK(). Esta função adiciona um número de classificação, que é um número seqüencial, a cada linha do conjunto de resultados ou dentro da partição do conjunto de resultados. A diferença entre RANK() e ROW_NUMBER() é que RANK() salta os valores duplicados. Quando há valores duplicados, a mesma classificação é atribuída, e uma lacuna aparece na seqüência para cada classificação duplicada. Veja o Exemplo 1 abaixo. Exemplo 1 SELECT RANK() OVER(ORDER BY sale_amount) AS row_number, sale_date, salesman_id, sale_amount FROM sale; Esta consulta retorna o resultado: rank_numbersale_datesalesman_idsale_amount 12020-04-21129500.00 22020-04-221311000.00 22020-04-221111000.00 42020-04-201112500.00 42020-04-201212500.00 62020-04-221222800.00 72020-04-211131000.00 Neste caso, RANK() atribui um número de classificação para cada registro como ROW_NUMBER(), mas para o mesmo valor em sale_amount, o número de classificação é o mesmo. Os vendedores 11 e 13 em 2020-04-22 alcançaram o mesmo valor de venda de $11.000. Portanto, eles têm o mesmo número de classificação, 2. Neste caso, ROW_NUMBER() atribuiu um número de classificação diferente. Observe que o próximo recorde não tem o número 3. RANK() salta o(s) número(s) de classificação das filas adicionais com o mesmo valor. Assim, após duas filas com o número 2, o próximo número é 4, não 3. É claro, RANK() também atribui números dentro das partições. Veja o Exemplo 2 abaixo. Exemplo 2 SELECT RANK() OVER(PARTITION BY sale_date ORDER BY sale_amount) AS row_number, sale_date, salesman_id, sale_amount FROM sale; Esta consulta retorna o resultado: rank_numbersale_datesalesman_idsale_amount 12020-04-201212500.00 12020-04-201112500.00 12020-04-21129500.00 22020-04-211131000.00 12020-04-221311000.00 12020-04-221111000.00 32020-04-221222800.00 A consulta acima dividiu o resultado definido em conjuntos de filas com a mesma data de venda. Por exemplo, uma partição contém as vendas em 2020-04-22. As linhas são numeradas separadamente para cada data de venda. Em 2020-04-22, os vendedores 11 e 13 têm o mesmo valor de venda de $11000. Portanto, estes registros têm ambos a classificação número 1, e o próximo registro tem a classificação número 3 porque a linha adicional é pulada. DENSE_RANK() A terceira função do ranking é DENSE_RANK(). Se você gostaria de atribuir o mesmo número a linhas com o mesmo valor em uma determinada coluna, mas não pular os próximos números, use DENSE_RANK(). DENSE_RANK() é semelhante a RANK(), mas com DENSE_RANK(), o número do ranking não é pulado para os mesmos valores. Veja o Exemplo 1 abaixo. Exemplo 1 SELECT DENSE_RANK() OVER(ORDER BY sale_amount) AS row_number, sale_date, salesman_id, sale_amount FROM sale; Esta consulta retorna o resultado: dense_rank_numbersale_datesalesman_idsale_amount 12020-04-21129500.00 22020-04-221311000.00 22020-04-221111000.00 32020-04-201112500.00 32020-04-201212500.00 42020-04-221222800.00 52020-04-211131000.00 Para o mesmo valor de venda, as filas têm o mesmo número. Entretanto, as próximas linhas não são puladas, e elas têm o próximo número seqüencial. Observe que para o mesmo valor de venda de $11.000 pelos vendedores 11 e 13 em 2020-04-22, o número de classificação atribuído é 2, mas para os dois registros seguintes com o valor de venda de $12.500, o número de classificação é 3. Esta função não salta o próximo número. RANK() funciona de maneira diferente. Neste caso, para o valor de venda de $12.500, RANK() atribuiria o número 4, pulando o 3 porque duas linhas tinham 2. DENSE_RANK() também funciona com partições. Veja o Exemplo 2 abaixo. Exemplo 2 SELECT DENSE_RANK() OVER(PARTITION BY sale_date ORDER BY sale_amount) AS row_number, sale_date, salesman_id, sale_amount FROM sale; Esta consulta retorna o resultado: dense_rank_numbersale_datesalesman_idsale_amount 12020-04-201212500.00 12020-04-201112500.00 12020-04-21129500.00 22020-04-211131000.00 12020-04-221311000.00 12020-04-221111000.00 22020-04-221222800.00 Neste caso, em 2020-04-22, os vendedores com o valor da venda se $11.000 tiverem o número 1, mas o próximo recorde tem o número 2, não 3 como com RANK(). PERCENT_RANK() A última função de classificação que vou discutir é PERCENT_RANK(). Esta função retorna o percentual de classificação. Veja o Exemplo 1 abaixo. Exemplo 1 SELECT PERCENT_RANK() OVER(ORDER BY sale_amount) AS row_number, sale_date, salesman_id, sale_amount FROM sale; Esta consulta retorna o resultado: percent_rank_numbersale_datesalesman_idsale_amount 02020-04-21129500.00 0.16666662020-04-221311000.00 0.16666662020-04-221111000.00 0.52020-04-201112500.00 0.52020-04-201212500.00 0.83333342020-04-221222800.00 12020-04-211131000.00 Esta consulta calcula a classificação relativa de cada linha no conjunto de resultados. O valor mais alto de venda é atribuído a 1 como a classificação percentual, e o valor mais baixo é atribuído a 0. Os valores entre eles são retornados como a classificação de um intervalo de valores, que são maiores do que 0 e menores do que 1. A meio caminho entre o valor mais alto e o mais baixo, o número da porcentagem é 0,5. Aqui, aos vendedores 11 e 12 em 2020-04-20 é atribuído o número percentual da classificação de 0,5. Os registros dos vendedores 11 e 13 em 2020-04-22 estão entre 0 e 0,5, portanto, eles têm a porcentagem de número 0,1666666. PERCENT_RANK() funciona de forma semelhante para partições de registros. Veja o Exemplo 2 abaixo. Exemplo 2 SELECT PERCENT_RANK() OVER(PARTITION BY sale_date ORDER BY sale_amount) AS row_number, sale_date, salesman_id, sale_amount FROM sale; Esta consulta retorna o resultado: percent_rank_numbersale_datesalesman_idsale_amount 02020-04-201212500.00 02020-04-201112500.00 02020-04-21129500.00 12020-04-211131000.00 02020-04-221311000.00 02020-04-221111000.00 12020-04-221222800.00 Em cada partição, a fileira mais alta retornada tem o grau 1, e a mais baixa tem o grau 0. Nestas partições, não há registros entre a mais alta e a mais baixa. Portanto, não há número percentual entre 0 e 1, como no exemplo anterior. Resumo Neste artigo, discuti as funções de ranking SQL, explicando sua sintaxe e utilizando-as em exemplos do mundo real. Se você gostaria de saber mais sobre as funções de ranking, veja o curso "Funções de Janela (Window Functions) em SQL"em LearnSQL.com.br ou leia os artigos "SQL Window Function Example With Explanations," "How to Use Rank Functions in SQL," e "Common SQL Funções de Janela (Window Functions) em SQL: Using Partitions With Ranking Functions". Tags: sql aprender sql rank