PostgreSQL equivalente per Top N con cravatte: limite "con legami"?
-
09-12-2019 - |
Domanda
Sto cercando qualcosa simile a questo in SQL Server:
SELECT TOP n WITH TIES FROM tablename
.
Conosco il LIMIT
in PostgreSQL, ma esiste l'equivalente di quanto sopra?Sono solo curioso di salvare una query extra ogni volta per me.
Se ho una tabella Numbers
con Attribute nums
: {10, 9, 8, 8, 2}
.Voglio fare qualcosa come:
SELECT nums FROM Numbers ORDER BY nums DESC LIMIT *with ties* 3
.
Dovrebbe restituire {10, 9, 8, 8}
perché ci vuole il top 3 più il 8
extra poiché lega l'altro.
Soluzione
There is no WITH TIES
clause in PostgreSQL like there is in SQL Server.
In PostgreSQL I would substitute this for 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;
To be clear, rank()
is right, dense_rank()
would be wrong (return too many rows).
Consider this quote from the SQL Server docs (from the link above):
For example, if expression is set to 5 but 2 additional rows match the values of the ORDER BY columns in row 5, the result set will contain 7 rows.
The job of WITH TIES
is to include all peers of the last row in the top n as defined by the ORDER BY
clause. rank()
gives the exact same result.
To make sure, I tested with SQL server, here is a live demo.
And here is a more convenient SQLfiddle.
Altri suggerimenti
Try this:
Output: 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
Output: 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