4

DBIx::Class結果セット検索でgroup_byを使用しています。各グループに対して返される結果は、常にグループ内の最小 ID を持つ行 (つまり、グループ内で最も古い行) です。代わりに、ID が最も高い行 (つまり、グループ内の最新の行) を取得する方法を探しています。

問題は基本的にこれと同じです: 各グループの最後のレコードを取得する ...生の SQL ではなく DBIx::Class を使用していることを除いて。

質問を文脈に入れるには:

音楽レビューの表があります

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' },
  }
);

これはほとんど機能しますが、最新ではなく、各グループの最も古いレビューを返します。どうすれば最新のものを入手できますか?

4

1 に答える 1

2

これが機能するためには、壊れたデータベースの動作に依存しています。group byを使用する場合、集計関数 (min、max など) を使用するか、group by 句で指定されていない限り、テーブルから列を選択することはできません。

MySQL では、マニュアルでさえこれが間違っていることを認めていますが、サポートしています。

あなたがする必要があると思うのは、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;
}

うん - それはより多くのクエリですが、それは理にかなっています - 2つのレビューが同じ日付にある場合はどうなりますか? DBはselectステートメントでどちらを返すかをどのように知る必要がありますか?

于 2011-08-22T14:15:04.793 に答える