Home > Enterprise >  Fetching a minimum of N rows, plus all peers of the last row
Fetching a minimum of N rows, plus all peers of the last row

Time:11-11

I have a sample table named assets which looks like this:

id name block_no
1 asset1 2
2 asset2 2
3 asset3 3

There can be any number of assets in a specific block. I need a minimum of 100 rows from the table, and containing all the data from the block_no. Like, if there are 95 rows to block_no 2 and around 20 on block_no 3, I need all 20 of block_no 3 as if I am fetching data in packets based on block_no.
Is this possible and feasible?

CodePudding user response:

Postgres 13 or later

There is a dead simple solution using WITH TIES in Postgres 13 or later:

SELECT *
FROM   assets
WHERE  block_no >= 2  -- your starting block
ORDER  BY block_no
FETCH  FIRST 100 ROWS WITH TIES;

This will return at least 100 rows (if enough qualify), plus all peers of the 100th row.

If your table isn't trivially small, an index on (block_no) is essential for performance.

See:

Older versions

Use the window function rank() in a subquery:

SELECT (a).*
FROM  (
   SELECT a, rank() OVER (ORDER BY block_no) AS rnk
   FROM   assets a
   ) sub
WHERE  rnk <= 100;

Same result.

I use a little trick with the row type to strip the added rnk from the result. That's an optional addition.

See:

  • Related