Um dos novos recursos do PostgreSQL 13 é o padrão SQL
WITH TIES
cláusula para usar com LIMIT
— ou, como o padrão chama isso, FETCH FIRST n ROWS
. Agradecimentos são devidos a Surafel Temesgen como autor inicial do patch; Tomas Vondra e sinceramente por algumas correções de código adicionais; e revisores Andrew Gierth e Erik Rijkers. Você pode ler a mensagem de confirmação. Os empates são muito frequentes ao classificar as coisas; por exemplo, em uma corrida de caucus, você pode ter muitos empates e, com certeza, não quer privar os participantes de seus prêmios! O que
WITH TIES
faz é bem simples:ele adiciona qualquer linha ou linhas a seguir ao seu conjunto de resultados, se elas tiverem uma classificação igual à última linha retornada pelo LIMIT
cláusula, de acordo com o ORDER BY
cláusula. Se você quiser apenas os dois funcionários com o maior salário, você pode fazer isso:
SELECT * FROM employees ORDER BY salary DESC LIMIT 2;
nome | salário | departamento |
---|---|---|
Alícia | 1600 | engenharia |
Oruga | 1500 | marketing |
Então você está ansioso para saber o salário da próxima pessoa? E se ela combina com Oruga e foi deixada de fora por puro acaso ou azar? Isso pode acontecer, como você bem sabe; e felizmente,
WITH TIES
agora está lá para salvar o dia. (Observe que, na realidade, não lidamos com WITH TIES
no LIMIT
cláusula como tal. Você tem que usar o FETCH FIRST
sintaxe, que é a exigida pelos padrões, para poder usar WITH TIES
.) SELECT * FROM employees ORDER BY salary DESC FETCH FIRST 2 ROWS WITH TIES;
nome | salário | departamento |
---|---|---|
Alícia | 1600 | engenharia |
Oruga | 1500 | vendas |
Conejo Branco | 1500 | marketing |
Lá! Coelho Branco tinha para ser listado, e agora ele é.
Algumas notas antes de você ficar muito louco.
LIMIT
(ou mais precisamente FETCH FIRST
) não promete mais retornar exatamente o número de linhas que você especificar. Você pode obter duas ou vinte linhas adicionais, ou 100 vezes o número de linhas que pediu. Entre outras coisas, isso significa que você precisa acompanhar quantas linhas você viu até agora, se estiver paginando os resultados. Acima, você tem três linhas, então para a próxima página você pula muitas adicionando o OFFSET
correto cláusula:SELECT * FROM employees
ORDER BY salary DESC
FETCH FIRST 2 ROWS WITH TIES
OFFSET 3;
nome | salário | departamento |
---|---|---|
Falso Tortuga | 1400 | marketing |
Duquesa | 1300 | vendas |
Liebre de Marzo | 1300 | engenharia |
Mais uma vez, recebemos três em vez de apenas dois que pedimos. Então, para a próxima página, você teria que pular seis. E assim por diante. Certifique-se de ter dedais suficientes para todos.
A outra coisa a ter em mente é que você deve certificar-se de usar apenas o
ORDER BY
cláusula que se adequa ao WITH TIES
cláusula; se você quisesse, digamos, ter as linhas do mesmo salário ordenadas por nome, você teria que usar uma subconsulta. Caso contrário, a distinção de nomes resolveria o empate no salário, de modo que a próxima linha não seria incluída. Por exemplo:SELECT * FROM (
SELECT * FROM employees
ORDER BY salary DESC
FETCH FIRST 2 ROWS WITH TIES) AS subq
ORDER BY salary DESC, name;
Esse recurso existe para ajudá-lo a mostrar todas as linhas que têm o mesmo valor — ele permite que você não discrimine algumas linhas de valor igual com base apenas na localização física na tabela.
Boa paginação!