 <p>If you are using a 11G R2, you could use listagg function. If not, it will be easy to find a different way</p> <pre><code> With distrib as (select O as dabegin, 17 as daend, 'under 18' as category from dual union all select 18 as dabegin ,25 as daend, 'between 18-25' as category from dual union all select 26 as dabegin ,30 as daend, 'between 26-30' as category from dual ) , games as (select p.player_id, count(*) as games_played from player p join game g on p.player_id = g.player1_id or p.player_id = g.player2_id group by p.player_id) select max(games_played), listagg(player_id,',') WITHIN GROUP (ORDER BY player_id) as 'winner(s)', category from distrib d, games g, players p where p.player_id=g.player_id and g. age between d.dabegin and daend group by g.category </code></pre>