Rails 4查询由单个属性唯一

问题描述 投票:20回答:7

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

我有三个对象,叫做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'>
ruby-on-rails postgresql activerecord arel
7个回答
30
投票

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

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

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


11
投票

请试试这个:

Item.select('distinct name')

4
投票

如果您只需要一个带有名称但没有ID的数组,您可以执行以下操作:

Item.pluck(:name).uniq

SQL查询结果:

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

**编辑**

uniq是在一系列记录上运行的。如果您期望有大量记录,请小心。 SQL Distinct要快得多。

如果是这样,使用vee的答案,使用map

Item.select('distinct name').map(:name)


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


2
投票

我还不能评论帖子,所以,把这作为问题的另一个答案。

如果有人仍然搜索这个,@BananaNeil's answer是正确的。然而,把distinct放在select并不适合我(Rails 5.2.2)。分开这两个确实解决了我的问题。

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

0
投票

对于Mysql,你可以使用groupONLY_FULL_GROUP_BY禁用,

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

Is there ANY_VALUE capability for mysql 5.6?


-1
投票

以下是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
© www.soinside.com 2019 - 2024. All rights reserved.