Equivalente do PostgreSQL para TOP n WITH TIES:LIMITE “com gravata”?
-
09-12-2019 - |
Pergunta
Estou procurando algo semelhante a isto no SQL Server:
SELECT TOP n WITH TIES FROM tablename
Eu sei sobre LIMIT
no PostgreSQL, mas existe o equivalente ao acima?Estou apenas curioso, pois isso salvaria uma consulta extra a cada vez para mim.
Se eu tiver uma mesa Numbers
com atributo nums
: {10, 9, 8, 8, 2}
.Eu quero fazer algo como:
SELECT nums FROM Numbers ORDER BY nums DESC LIMIT *with ties* 3
Deveria retornar {10, 9, 8, 8}
porque leva os 3 primeiros mais o extra 8
já que amarra o outro.
Solução
Não há WITH TIES
cláusula em PostgreSQL como há em servidor SQL.
No PostgreSQL eu substituiria isso por TOP n WITH TIES .. ORDER BY <something>
:
WITH cte AS (
SELECT *, rank() OVER (ORDER BY <something>) AS rnk
FROM tbl
)
SELECT *
FROM cte
WHERE rnk <= n;
Para ser claro, rank()
está certo, dense_rank()
estaria errado (retornar muitas linhas).
Considere esta citação da documentação do SQL Server (no link acima):
Por exemplo, se a expressão for definida como 5, mas 2 linhas adicionais correspondem aos valores da ordem por colunas na linha 5, o conjunto de resultados conterá 7 linhas.
O trabalho de WITH TIES
é incluir todos os pares da última linha no topo n conforme definido pelo ORDER BY
cláusula. rank()
dá exatamente o mesmo resultado.
Para ter certeza, testei com SQL server, aqui está um demonstração ao vivo.
E aqui está um mais conveniente SQLfiddle.
Outras dicas
Experimente isto:
Saída:10, 9, 8, 8
with numbers (nums) as (
values (10), (9), (8), (8), (2)
)
SELECT nums FROM Numbers
WHERE nums in (SELECT DISTINCT nums FROM Numbers ORDER BY nums DESC LIMIT 3)
ORDER BY nums DESC
Saída:10,10,9,8,8
with numbers (nums) as (
values (10), (9), (8), (8), (2), (10)
)
SELECT nums FROM Numbers
WHERE nums in (SELECT DISTINCT nums FROM Numbers ORDER BY nums DESC LIMIT 3)
ORDER BY nums DESC