如何在 DBIx::Class 结果集搜索中检索每个组中的最新记录?

发布于 2024-11-30 22:18:47 字数 881 浏览 1 评论 0原文

我在 DBIx::Class 结果集搜索。为每个组返回的结果始终是组中具有最低 id 的行(即组中最旧的行)。我正在寻找一种方法来获取具有最高 id 的行(即组中的最新行)。

问题本质上是一样的: 检索每个组中的最后一条记录 ...除了我使用的是 DBIx::Class 而不是原始 SQL。

将问题放在上下文中:

我有一个音乐评论表,

review
------
id
artist_id
album_id
pub_date
...other_columns...

对于任何给定的 Artist_id/album_id 都可以有多个评论。 我想要最新的评论,按日期降序排列,每个 Artist_id/album_id 的评论不超过一条。

我尝试使用以下方法来执行此操作:

$schema->resultset('Review')->search(
  undef,
  {
    group_by => [ qw/ artist_id album_id / ],
    order_by => { -desc => 'pub_date' },
  }
);

这几乎有效,但返回每个组中最旧的评论而不是最新的评论。 我怎样才能得到最新的?

I'm using group_by in a DBIx::Class resultset search. The result returned for each group is always the row in the group with the lowest id (i.e the oldest row in the group). I'm looking for a way to get the row with the highest id (i.e. the newest row in the group) instead.

The problem is fundamentally the same as this:
Retrieving the last record in each group
...except that I'm using DBIx::Class not raw SQL.

To put the question in context:

I have a table of music reviews

review
------
id
artist_id
album_id
pub_date
...other_columns...

There can be multiple reviews for any given artist_id/album_id.
I want the most recent reviews, in descending date order, with no more than one review per artist_id/album_id.

I tried to do this using:

$schema->resultset('Review')->search(
  undef,
  {
    group_by => [ qw/ artist_id album_id / ],
    order_by => { -desc => 'pub_date' },
  }
);

This nearly works, but returns the oldest review in each group instead of the newest.
How can I get the newest?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

廻憶裏菂餘溫 2024-12-07 22:18:47

为此,您依赖于损坏的数据库行为。当您使用 group by 时,您不应该能够从表中选择列,除非它们使用聚合函数(最小值、最大值等)或在 group by 子句中指定。

在 MySQL 中,甚至手册也承认这是错误的< /a> - 尽管它支持它。

我认为你需要做的是获取评论的最新日期,使用 max(pub_date):

my $dates = $schema->resultset('Review')->search({},
  {
    select   => ['artist_id', 'album_id', {max => 'pub_date'}],
    as       => [ qw(artist_id album_id recent_pub_date) ],
    group_by => [ qw(artist_id album_id) ],
  }
);

然后循环获取评论:

while (my $review_date = $dates->next) {
    my $review = $schema->resultset('Review')->search({
        artist_id => $review_date->artist_id,
        album_id  => $review_date->album_id,
        pub_date  => $review_date->get_column('recent_pub_date'),
    })->first;
}

是的 - 这是更多查询,但这是有道理的 - 如果两个评论在同一日期怎么办 -数据库应该如何知道在 select 语句中返回哪一个?

For this to work you are relying on broken database behaviour. You should not be able to select columns from a table when you use group by unless they use an aggregate function (min, max etc.) or are specified in the group by clause.

In MySQL, even the manual admits this is wrong - though it supports it.

What I think you need to do is get the latest dates of the reviews, with max(pub_date):

my $dates = $schema->resultset('Review')->search({},
  {
    select   => ['artist_id', 'album_id', {max => 'pub_date'}],
    as       => [ qw(artist_id album_id recent_pub_date) ],
    group_by => [ qw(artist_id album_id) ],
  }
);

Then loop through to get the review:

while (my $review_date = $dates->next) {
    my $review = $schema->resultset('Review')->search({
        artist_id => $review_date->artist_id,
        album_id  => $review_date->album_id,
        pub_date  => $review_date->get_column('recent_pub_date'),
    })->first;
}

Yep - it's more queries but it makes sense - what if two reviews are on the same date - how should the DB know which one to return in the select statement?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文