Rails 4查询由单个属性唯一

时间:2013-08-05 03:45:20

标签: ruby-on-rails postgresql activerecord arel

所以这不仅仅是一个问题,而是我想要做的事情。

我有三个对象,比如项目

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

我想做一个只返回每个唯一“name”属性中的一个的查询。

Item.select('distinct(name), items.*')

这样的东西

但这不起作用,它仍然会返回所有三个项目。

如何形成此查询以便它只返回:

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

7 个答案:

答案 0 :(得分:31)

如果您想恢复整个模型,但仍保持唯一性,可以使用:

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

我只用Postgres数据库对此进行了测试。它可能适用于或不适用于mysql。

答案 1 :(得分:11)

请试试这个:

Item.select('distinct name')

答案 2 :(得分:4)

如果您只需要一个名称不含ID的数组,您可以这样做:

Item.pluck(:name).uniq

SQL查询结果:

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

**编辑**

{1}在记录数组上运行。如果您期望有大量记录,请小心。 SQL Distinct要快得多。

如果是,请使用上面的回答,uniq

map

答案 3 :(得分:2)

在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

答案 4 :(得分:2)

我尚无法评论帖子,因此,将其作为问题的另一个答案。

如果仍然有人在搜索此内容,则@BananaNeil's answer是正确的。但是,将distinct放在select中对我来说不起作用(Rails 5.2.2)。分离这两个确实解决了我的问题。

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

答案 5 :(得分:0)

对于Mysql,您可以使用group并禁用ONLY_FULL_GROUP_BY

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

请参阅Is there ANY_VALUE capability for mysql 5.6?

答案 6 :(得分:0)

以下是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