web-dev-qa-db-ja.com

Rails 1つの属性で一意の4つのクエリ

ですから、これは何よりも問題ですが、これが私がやろうとしていることです。

アイテムと呼ばれる3つのオブジェクトがあります

_<Item id: 1, name: 'Book'>
<Item id: 2, name: 'Car'>
<Item id: 3, name: 'Book'>
_

それぞれの一意の「名前」属性を1つだけ返すクエリを実行したいと思います。

Item.select('distinct(name), items.*')のようなもの

ただし、これは機能しませんが、3つすべてのアイテムが返されます。

次のクエリのみを返すようにこのクエリを作成するにはどうすればよいですか。

_<Item id: 1, name: 'Book'>
<Item id: 2, name: 'Car'>
_
21
goddamnyouryan

モデル全体を元に戻しながら、一意性を維持したい場合は、次を使用できます。

Item.select('distinct on (name) *')

私はこれをPostgresデータベースでのみテストしました。 mysqlで動作する場合と動作しない場合があります。

31
BananaNeil

これを試してください:

Item.select('distinct name')
11
vee

IDなしで名前付きの配列のみが必要な場合は、次のことができます。

_Item.pluck(:name).uniq
_

SQLクエリの結果:

_#=> SELECT `items`.`name` FROM `items`
_

**編集**

uniqは、レコードの配列に対して実行されます。大量のレコードが予想される場合は注意してください。 SQLDistinctははるかに高速です。

その場合は、上記のveeの回答をmapとともに使用してください。

Item.select('distinct name').map(:name)

4
Frexuz

私はまだ投稿にコメントすることができないので、これを質問の別の答えとして置きます。

誰かがまだこれを検索している場合、 @ BananaNeilの答え は正しいです。しかし、distinctselectに入れることは私にはうまくいきませんでした(Rails5.2.2)。これら2つを分離することで、私の問題は解決しました。

klass.where(
  # Your query or whatever
).distinct.select('on (attribute) *')
3
Oguzhan Ozdemir

以下はRails ORMクエリです。これはすべての最新のRailsバージョンRails 5.Xで目的の結果を生成します。

@unique_values= []
Model.all.group_by(&:column_name).each do |key, val|
    if val.count == 1
      @unique_values << val
    else
      @unique_values << val.first
    end
end
0
Ankit Varshney

Rails 4 try Items.all.to_a.uniq { |item| item.name }

Rails 3では、Items.uniq_by { |item| item.name }を実行できるはずです。

配列でuniqを呼び出すと、その配列にブロックを渡して、一意性を判断する方法を指定できます。 Rails 3では、以前はuniq_byを使用できましたが、Rails 4で非推奨になりました。したがって、私が見つけた1つの方法は、 ActiveRecord Relationを配列に変換し、その上でuniqを呼び出します。

0
TalkativeTree

Mysqlの場合、groupを使用できます ONLY_FULL_GROUP_BY 無効、

Item.group(:name).to_sql
=> "SELECT `items`.* FROM `items`  GROUP BY name"

mysql 5.6のANY_VALUE機能はありますか? を参照してください。

0
fangxing