Rails:如何从列中获取唯一值


73

如何从表格的列中获取唯一值?例如,我有此产品表:

ID NAME CATEGORY
1 name1 1st_cat
2 name2 2nd_cat
3 name3 1st_cat

在这里,我只想获取2个值-1st_cat和2nd_cat:

<%Products.each do |p|%>
<%=p.category%>
<%end%>

您还可以将Product.group(“ category_id”)
分组

2
以下所有可能的方式-它应该指出的是Products.uniq.pluck(:类)是最有效的方式
哟Ludke

3
只是事后的想法;如果您的Model名称是复数形式,那么根据Rails的观点,您做错了。
rcd

Answers:


166

另外两种方式:

Product.select(:category).map(&:category).uniq # Ruby does the work

Product.uniq.pluck(:category) # DB does the work (superior)

对于Rails> = 5.1,请使用:

Product.distinct.pluck(:category) # DB does the work (superior)

...因为Relation#uniq弃用


2
我正是在寻找这个:Products.pluck(:category).uniq很棒!+1 :)
KM拉基布尔伊斯兰教2012年

7
这会将所有产品拉入Ruby数组,而不是在数据库中完成工作。
superluminary 2013年

1
@superluminary正在将所有产品拉入Ruby数组,而不是让DB做推荐的工作?
8bithero

13
User.uniq.pluck(:source)产生,SELECT DISTINCT "users"."source" FROM "users"所以我认为它不会将所有记录加载到ruby数组中。
拉斐尔·奥利维拉

3
对于Rails> = 5.1,请使用Products.distinct.pluck(:category)
davegson


11

这将完成数据库服务器中的所有工作。结果是一个简单的数组。

<% Product.distinct(:category).pluck(:category).each do |category|
    <%= category %>
<% end %>

Rails将生成可在任何数据库(Postgres,MySQL等)上运行的SQL。

SELECT DISTINCT "products"."category" FROM "products"

8

我建议使用,Products.all.distinct.pluck(:category)因为uniq从导轨5开始已弃用,并且将在导轨5.1上将其删除


6

试试看(在rails控制台中)

Product.group(:category)

Product.group(:category).each { |p| p.name }

5
这仅适用于MySql数据库(可能也是sqlite,但在Postgres或MSSQL上绝对不好)
jamesc 2012年

在sqlite上工作
Geoffrey H

您必须:Product.select(:category).group(:category)才能使其在Postgresql上运行(我猜是MSSQL)。
Ben Trewern

4

对于postgres

<% Product.select("DISTINCT ON (category) *").each do |category|
    <%= category %>
    <%= name %>
<% end %>

更新资料

更好

<% Product.select(%(DISTINCT ON (category) "#{Product.table_name}".*)).each do |category|
    <%= category %>
    <%= name %>
<% end %>

因为这样做可能会返回错误的列joins(例如,id从联接表返回列,但不能products


投票是因为当您需要整个活动记录关系而不是采摘值数组时,此解决方案为我工作。
Arth Thakkar

0

需要获得唯一的输出,并且尝试使用“ uniq”方法失败。尝试了几种未成功发布在此处的解决方案。我正在使用devise,这使我可以访问current_user方法并使用两个表,一个表是联接(项has_many:things)。

这个解决方案最终对我有用:

@current_user.things.select(:item_fk).distinct.each do |thing|
 <%= thing.item.attribute %>
<% end %>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.