Rails:从列中select唯一的值
我已经有一个工作的解决scheme,但我真的想知道为什么这不起作用:
ratings = Model.select(:rating).uniq ratings.each { |r| puts r.rating }
它select,但不打印唯一值,它打印所有值,包括重复。 它在文档中: http : //guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields
Model.select(:rating)
结果是一个Model
对象的数组。 不是简单的评级。 而从uniq
的angular度来看,它们完全不同。 你可以使用这个:
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
,因为它只返回唯一值。 这是更好的,因为这意味着它返回的行less了,而且应该比返回一些行更快,然后告诉Railsselect唯一值。
Model.select('DISTINCT rating')
当然,这是提供你的数据库理解的DISTINCT
关键字,大多数应该。
这也可以。
Model.pluck("DISTINCT rating")
Model.uniq.pluck(:rating) # SELECT DISTINCT "models"."rating" FROM "models"
这有没有使用SQLstring的优点,而不是实例化模型
Model.select(:rating).uniq
此代码作为“DISTINCT”(不像Array#uniq),因为rails 3.2
如果你还想select额外的字段:
Model.select('DISTINCT ON (models.ratings) models.ratings, models.id').map { |m| [m.id, m.ratings] }
如果有人正在寻找与Mongoid相同的,那就是
Model.distinct(:rating)
有些答案没有考虑到OP想要一系列值
其他答案不能很好地工作,如果你的模型有成千上万的logging
这就是说,我认为一个好的答案是:
Model.uniq.select(:ratings).map(&:ratings) => "SELECT DISTINCT ratings FROM `models` "
因为,首先生成一个模型数组(由于select而缩小了大小),然后提取这些选定模型的唯一属性(评级)
如果我正确的话,那么:
当前查询
Model.select(:rating)
正在返回对象的数组,你已经写了查询
Model.select(:rating).uniq
uniq应用于对象数组,每个对象都有唯一的id。 uniq正在正确地执行它的工作,因为数组中的每个对象都是uniq。
有很多方法可以select不同的评分:
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查询find不同的数据。
这些查询将被视为“伦敦”和“伦敦”也意味着它将忽略空间,这就是为什么它会在您的查询结果中select“伦敦”一次。
第三和第四个查询:
通过SQL查询查找数据,并针对不同的数据应用ruby uniq mehtod。 这些查询将被视为“伦敦”和“伦敦”不同,这就是为什么它会在您的查询结果中select“伦敦”和“伦敦”。
请更喜欢附加图片以获得更多的理解,并看看“等待RFP”。
Model.select(:rating).distinct
用sql收集uniq列的另一种方法是:
Model.group(:rating).pluck(:rating)