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:

my $rs = $schema->resultset('cds'); $rs = $rs->search({ genre => 'rock' });
... and I now would like to do something like:
$rs = $rs->limit_per_artist( 5 );
... to retrieve the most recent 5 CDs for each rocker.

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.


The way forward always starts with a minimal test.

In reply to Get top N rows in each group with DBIx::Class by 1nickt

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.