Postgresql – Postgres: how to limit the number of query results by aggregate type

aggregatepostgresqlquery

Consider the following table definition

CREATE TABLE associations (
    id SERIAL PRIMARY KEY,
    resource_id integer,
    target_id integer,
    relation_id integer
);

which is used for specifying the association of a resource to a target by means of a relation:

296 10  49  4 <--
297 10  50  4 <--
298 10  51  4 <--
299 10  52  4
300 10  53  4
301 10  54  4
302 10  55  4
303 10  56  5 <--
304 10  57  5 <--
305 10  58  7
306 10  59  7
307 10  60  7
308 10  61  7
309 10  62  7
310 10  64  8 <--
316 11  80  8 <--
320 11  81  8 <--
321 11  82  8 <--
322 11  83  8
  • resource 10 is associated to targets [49, 50, 51, 52, 53, 54, 55] by relation 4
  • resource 10 is also associated to targets [56, 57] by relation 5

How can one query the associations table to get the targets of resources for specific relations (e.g. 4, 5 and 8) while limiting the number of returned targets per relation?

For example if we were to limit the number of targets to 3 on relations 4, 5 and 8 we should obtain the following result:

10 | 49, 50, 51 | 4
10 |     56, 57 | 5
10 |         64 | 8
11 | 80, 81, 82 | 8

Thank you.

Best Answer

WITH 
cte AS ( SELECT resource_id, 
                target_id,
                relation_id, 
                ROW_NUMBER() OVER ( PARTITION BY resource_id, relation_id 
                                    ORDER BY id ) rn
         FROM associations
         WHERE relation_id IN (4, 5, 8) )
SELECT resource_id, STRING_AGG(target_id::TEXT, ','::TEXT), relation_id
FROM cte
WHERE rn <= 3
GROUP BY resource_id, relation_id

fiddle