我已经有了一个可行的解决方案,但我真的很想知道为什么这不起作用:
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)
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.select('DISTINCT ON (models.ratings) models.ratings, models.id').map { |m| [m.id, m.ratings] }
Model.select(:rating).uniq
此代码自 rails 3.2 起作为“DISTINCT”(而不是 Array#uniq)工作
Rails 6 以上(?)应该是
Model.select(:rating).distinct
Model.uniq.pluck(:rating)
# SELECT DISTINCT "models"."rating" FROM "models"
这样做的好处是不使用sql字符串,不实例化模型
Model.select(:rating).distinct
使用sql收集uniq列的另一种方法:
Model.group(:rating).pluck(:rating)
如果我正要走的话:
当前查询
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
还有一件事,第一个和第二个查询:通过 SQL 查询查找不同的数据。
这些查询将被视为“london”,而“london”同样意味着它将忽略空格,这就是为什么它会在查询结果中选择“london”一次。
第三次和第四次查询:
通过 SQL 查询查找数据,对于不同的数据应用 ruby uniq 方法。 这些查询将被视为“london”和“london”不同,这就是为什么它会在查询结果中选择“london”和“london”。
请更喜欢附图以方便理解,并查看“参观/等待 RFP”。
如果有人正在寻找与 Mongoid 相同的东西,那就是
Model.distinct(:rating)
一些答案没有考虑OP想要一个值数组
如果您的模型有数千条记录,其他答案则效果不佳
也就是说,我认为一个好的答案是:
Model.uniq.select(:ratings).map(&:ratings)
=> "SELECT DISTINCT ratings FROM `models` "
因为,首先生成一个模型数组(由于选择而尺寸减小),然后提取这些所选模型具有的唯一属性(评级)
您可以使用以下 Gem:active_record_distinct_on
Model.distinct_on(:rating)
产生以下查询:
SELECT DISTINCT ON ( "models"."rating" ) "models".* FROM "models"
在我的场景中,在按创建日期对它们进行排序、应用偏移量和限制后,我想要一个不同的
names
列表。基本上是 ORDER BY
、DISTINCT ON
的组合
您需要做的就是将
DISTINCT ON
放入 pluck
方法中,如 follow
Model.order("name, created_at DESC").offset(0).limit(10).pluck(Arel.sql("DISTINCT ON (name) name"))
这将返回一组不同的
names
。
Model.pluck("DISTINCT column_name")