Getting the "latest" related record from a SQL DB

Andrew Beverley andy at andybev.com
Sun Oct 12 17:00:10 BST 2014


On Thu, 2014-10-09 at 13:28 +0100, Andrew Beverley wrote:
> I have a table (say "artist", couldn't resist...) that has a one-to-many
> relationship to another table (say "album"). The album table has a field
> which references the artist table's ID. So one artist can have many
> albums.
> ...
> But what if I want to fetch an artist's details and his latest album? I
> can select the artist from the artists table and then join the albums
> table. But to get the latest album I'd have to use a max function (say
> on the album's date), with which it isn't possible to get the related
> fields in the same row.

Thanks for all the replies. Two good options from several people: limit
the result to one row, or use a sub-select.

What I failed to say was that as well as doing this for a single artist
as per my question, I'd like to also be able to do it for several
artists. Therefore (I think) I can't use either of those options without
doing several database queries. I also like to avoid sub-selects as
MySQL has a tendency to optimise them badly (as Gareth said).

What I also failed to say was that I'm using DBIC and want to keep
things database agnostic.

So, I used Bill's suggestion, which seems to work well
(http://london.pm.org/pipermail/london.pm/Week-of-Mon-20141006/025481.html)

To get it to work with DBIC I had to create a custom join condition.
Something like:

$class->might_have(
    album_later => 'Album',
    sub {
        my $args = shift;

        return {
            "$args->{foreign_alias}.artist_id"  => {
                -ident => "$args->{self_alias}.artist_id"
            },
            "$args->{foreign_alias}.released" => {
                '>' => \"$args->{self_alias}.released"
            },
        };
    }
);

And then add the relevant search criteria when using it:

    $search = {
        {'album' => 'album_later'},
        ...
    }

Thanks again for all the replies.

Andy




More information about the london.pm mailing list