私はすでに実用的な解決策を持っていますが、なぜこれがうまくいかないのかを知りたいです。
ratings = Model.select(:rating).uniq
ratings.each { |r| puts r.rating }
選択しますが、一意の値は表示しません。重複を含むすべての値を表示します。そしてそれはドキュメントにあります。 http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields
Model.select(:rating)
これの結果はModel
オブジェクトのコレクションです。明白な評価ではありません。そしてuniq
の観点からは、それらは完全に異なります。これを使うことができます:
Model.select(:rating).map(&:rating).uniq
またはこれ(最も効率的)
Model.uniq.pluck(:rating)
# Rails 5+
Model.distinct.pluck(:rating)
どうやら、Rails 5.0.0.1以降では、上記のように "トップレベル"のクエリでしか動作しません。コレクションプロキシ(たとえば "has_many"リレーション)には作用しません。
Address.distinct.pluck(:city) # => ['Moscow']
user.addresses.distinct.pluck(:city) # => ['Moscow', 'Moscow', 'Moscow']
この場合は、クエリの後で重複排除します
user.addresses.pluck(:city).uniq # => ['Moscow']
Model.select
を使うつもりなら、DISTINCT
を使ってもいいでしょう。ユニークな値しか返さないからです。これはより少ない行数を返すことを意味し、いくつかの行数を返してRailsに一意の値を選択するように指示するよりもわずかに速いはずです。
Model.select('DISTINCT rating')
もちろん、これはあなたのデータベースがDISTINCT
キーワードを理解するために提供されており、ほとんどはそうすべきです。
これもうまくいきます。
Model.pluck("DISTINCT rating")
Model.uniq.pluck(:rating)
# SELECT DISTINCT "models"."rating" FROM "models"
これは、SQL文字列を使用せず、モデルをインスタンス化しないという利点があります。
追加のフィールドも選択したい場合は、
Model.select('DISTINCT ON (models.ratings) models.ratings, models.id').map { |m| [m.id, m.ratings] }
Model.select(:rating).uniq
Rails 3.2 から、このコードは(Array#uniqではなく) 'DISTINCT'として機能します。
私が順調に進んでいるなら:
現在のクエリ
Model.select(:rating)
オブジェクトの配列を返している、あなたはクエリを書いている
Model.select(:rating).uniq
uniqはオブジェクトの配列に適用され、各オブジェクトは一意のIDを持ちます。配列内の各オブジェクトはuniqであるため、uniqはそのジョブを正しく実行しています。
明確な評価を選択するには多くの方法があります。
Model.select('distinct rating').map(&:rating)
または
Model.select('distinct rating').collect(&:rating)
または
Model.select(:rating).map(&:rating).uniq
または
Model.select(:name).collect(&:rating).uniq
もう1つ、1番目と2番目のクエリ:SQLクエリによって異なるデータを見つける。
これらのクエリは "london"と "london"が同じであると見なされますが、スペースを無視することを意味します。そのため、クエリ結果で一度に "london"を選択します。
3番目と4番目のクエリ:
sQLクエリとRuby uniq mehtodを適用した明確なデータのためのデータ検索これらのクエリでは "london"と "london"が異なると見なされるため、クエリ結果で 'london'と 'london'が選択されます。
理解を深めるために添付画像をご希望の場合は、「Toured/Awaiting RFP」をご覧ください。
いくつかの答えは、OPが望んでいることを考慮に入れていない値の配列
モデルに何千ものレコードがある場合、他の回答はうまく機能しません。
それは言った、私は良い答えがあると思います:
Model.uniq.select(:ratings).map(&:ratings)
=> "SELECT DISTINCT ratings FROM `models` "
なぜなら、最初にModelの配列(selectのためにサイズが縮小されている)を生成し、次にそれらの選択されたモデルが持つ唯一の属性(rating)を抽出するからです。
誰かがMongoidで同じことを探しているなら、それは
Model.distinct(:rating)
Sqlを使ってユニークなカラムを集めるもう一つの方法:
Model.group(:rating).pluck(:rating)
Model.select(:rating).distinct