所以这不仅仅是一个问题,而是我想要做的事情。
我有三个对象,叫做Items
<Item id: 1, name: 'Book'>
<Item id: 2, name: 'Car'>
<Item id: 3, name: 'Book'>
我想做一个只返回每个唯一“名称”属性之一的查询。
像Item.select('distinct(name), items.*')
之类的东西
这不起作用,它仍然返回所有三个项目。
如何形成此查询以便它只返回:
<Item id: 1, name: 'Book'>
<Item id: 2, name: 'Car'>
如果您想要恢复整个模型,但仍保持唯一性,可以使用:
Item.select('distinct on (name) *')
我只用Postgres数据库对它进行了测试。它可能适用于也可能不适用于mysql。
请试试这个:
Item.select('distinct name')
如果您只需要一个带有名称但没有ID的数组,您可以执行以下操作:
Item.pluck(:name).uniq
SQL查询结果:
#=> SELECT `items`.`name` FROM `items`
**编辑**
uniq
是在一系列记录上运行的。如果您期望有大量记录,请小心。 SQL Distinct要快得多。
如果是这样,使用vee的答案,使用map
:
Item.select('distinct name').map(:name)
在Rails 4中尝试Items.all.to_a.uniq { |item| item.name }
在Rails 3中你应该能够做Items.uniq_by { |item| item.name }
当你在一个数组上调用uniq
时,你可以传递一个块来指示如何确定唯一性。在Rails 3中你曾经能够使用uniq_by
,但它在Rails 4中被弃用了。所以我找到的一种方法是将ActiveRecord Relation转换为数组并在其上调用uniq
。
我还不能评论帖子,所以,把这作为问题的另一个答案。
如果有人仍然搜索这个,@BananaNeil's answer是正确的。然而,把distinct
放在select
并不适合我(Rails 5.2.2)。分开这两个确实解决了我的问题。
klass.where(
# Your query or whatever
).distinct.select('on (attribute) *')
对于Mysql,你可以使用group
与ONLY_FULL_GROUP_BY禁用,
Item.group(:name).to_sql
=> "SELECT `items`.* FROM `items` GROUP BY name"
以下是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