1nickt has asked for the wisdom of the Perl Monks concerning the following question:
Hi all, I am seeking wisdom from those experienced in the deep magic of DBIx::Class. What I need to do is return a subset of rows from an SQL query, being the top N results in each group.
This problem is actually part of adding a feature to the CPAN Testers API, but for the sake of argument, let's use the standard DBIC metaphor of a music collection. Having started with all CDs, and filtered for musical genre, I want to receive only the most recent N albums by each artist in the result set.
In SQL I can do this with row_number(), or, for MySQL, a workaround with user variables. Something like:
set @artist = ''; set @num = 1; select * from ( select c.name, c.artist, @num := if(@artist = c.artist, @num + 1, 1) as row_number, @artist := s.artist as dummy from cds as c ) as results where results.row_number <= 5;
With DBIC I have already produced a result set spec (but not queried the DB yet) with something like:
... and I now would like to do something like:my $rs = $schema->resultset('cds'); $rs = $rs->search({ genre => 'rock' });
... to retrieve the most recent 5 CDs for each rocker.$rs = $rs->limit_per_artist( 5 );
I can see a couple of different ways to do it that involve multiple passes over the table(s), but I really need a single-pass solution like the SQL shown. Any pointers much appreciated.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Get top N rows in each group with DBIx::Class
by NetWallah (Canon) on Nov 26, 2017 at 01:35 UTC | |
by 1nickt (Canon) on Nov 26, 2017 at 03:18 UTC | |
|
Re: Get top N rows in each group with DBIx::Class
by shadowsong (Pilgrim) on Nov 26, 2017 at 18:30 UTC | |
by 1nickt (Canon) on Nov 26, 2017 at 20:22 UTC | |
|
Re: Get top N rows in each group with DBIx::Class
by chacham (Prior) on Nov 27, 2017 at 12:40 UTC | |
by 1nickt (Canon) on Nov 27, 2017 at 13:07 UTC | |
by chacham (Prior) on Nov 27, 2017 at 13:20 UTC | |
by 1nickt (Canon) on Nov 27, 2017 at 13:26 UTC | |
by chacham (Prior) on Nov 27, 2017 at 13:31 UTC |