PostgreSQL equivalent for TOP n WITH TIES: LIMIT "with ties"? PostgreSQL equivalent for TOP n WITH TIES: LIMIT "with ties"? sql sql

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:

SELECT

[ 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;

db<>fiddle demo