2017-04-25 8 views
3

タイトルの謝罪として、私の問題を簡潔に説明する方法がわかりません。ActiveRecordは、独自の一意性と最大列の値に基づいて選択します。

データベースにname,yearversionの複数のインスタンスがあるとします。以下の例:

| id | name  | year | version | 
|----|-----------|--------|---------| 
| 1 | Blockhead | 2010 | 1  | 
| 2 | Blockhead | 2010 | 2  | 
| 3 | Jughead | 2011 | 1  | 

私は唯一の名前と年がユニークな結果を返しますが、それだけで名/年の一意の組み合わせの最新バージョンを返すようにしたいです。

| id | name  | year | version | 
|----|-----------|--------|---------| 
| 2 | Blockhead | 2010 | 2  | 
| 3 | Jughead | 2011 | 1  | 

を私がグループ化されたデータセットを持っていたいのですが...しかし、SQL/ARの私の知識はこの点に限定されていると私は何を適切分からない可能であれば:つまり、私は返すようにしたいです解決策になるでしょう。私は現在、すべてのレコードを取得し、私が望んでいないものを除外しますが、それは控えめな解決策です。

@items = ::Item.active.paginate(per_page: 30, page: page || 1).to_a 

# Do not show a given item unless it's the latest version 
@items.delete_if do |item| 
    @items.any? do |other| 
    other.id != item.id && 
     other.read_attribute(:name) == item.read_attribute(:name) && 
     other.year == item.year && 
     other.version > item.version 
    end 
end 

答えて

0

SO関連の質問に見てみましょう:あなたのケースでは、必要なデータを選択するための最も簡単なクエリはなりRetrieving the last record in each group

SELECT name, year, MAX(version) as version 
FROM items 
GROUP BY name, year; 

あなたは追加の列(id用を選択したい場合は例)、またはグループ化された結果を避けるには、サブクエリを使用します:

SELECT * FROM items 
WHERE id IN (
    SELECT MAX(id) 
    FROM items 
    GROUP BY name, year); 

このコードは、MAX(id)がグループの最新versionの行のidを与えると仮定します。このクエリの

Railsのコード:

sub_query = Item.select("MAX(id)").group(:name, year).to_sql 
Items.where("id iN (?)", subquery) 
関連する問題