PostgreSQL equivalent for TOP n WITH TIES: LIMIT "with ties"?
Postgres 13 finally adds WITH TIES
. See:
There is no WITH TIES
clause up to PostgreSQL 12, 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 cteWHERE 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 thevalues 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.
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
PostgreSQL already supports OFFEST FETCH
clause and starting from version 13 it will support FETCH FIRST WITH TIES
:
[ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } { ONLY | WITH TIES } ]
The WITH TIES option is used to return any additional rows that tie for the last place in the result set according to the ORDER BY clause; ORDER BY is mandatory in this case.
Query:
SELECT nums FROM Numbers ORDER BY nums DESCFETCH NEXT 3 ROWS WITH TIES;