96

How can I get unique values from column in the table? For example, I have this Products table:

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

Here I want to get only 2 values - 1st_cat and 2nd_cat:

<%Products.each do |p|%>
<%=p.category%>
<%end%>
3
  • also u can group Product.group("category_id")
    – Neelesh
    Commented Dec 21, 2013 at 7:05
  • 2
    All of the possible ways below - It should be noted that Products.uniq.pluck(:category) is the most efficient way
    – Yo Ludke
    Commented Mar 19, 2014 at 12:30
  • 3
    Just an afterthought; if your Model names are plural, you're doing it wrong, in terms of Rails' opinion.
    – rcd
    Commented Jul 26, 2014 at 23:07

9 Answers 9

207

Two more ways:

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

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

For Rails >= 5.1 use:

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

...because Relation#uniq was deprecated.

10
  • 2
    I was exactly looking for this : Products.pluck(:category).uniq Superb! +1 :) Commented Nov 5, 2012 at 20:56
  • 8
    This will pull all the products into a Ruby array, rather than doing the work in the database. Commented Apr 9, 2013 at 14:05
  • 1
    @superluminary is pulling all the products into a Ruby array, rather than having the DB do the work recommended?
    – 8bithero
    Commented Sep 24, 2013 at 4:54
  • 13
    User.uniq.pluck(:source) produces SELECT DISTINCT "users"."source" FROM "users" so I don't think it is loading all records into a ruby array. Commented Sep 1, 2014 at 21:48
  • 4
    For Rails >= 5.1 use Products.distinct.pluck(:category)
    – davegson
    Commented May 12, 2018 at 12:12
27

I think you can do this:

<% Products.select("DISTINCT(CATEGORY)").each do |p| %>
<%= p.category %>
<% end %>

Source: http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields

2
  • I'm a Rails newbie myself (just working through the tutorials now ;-) ) I Googled it. Commented Dec 3, 2011 at 18:29
  • works only if you want 1 column, other column are not selected
    – srghma
    Commented Dec 7, 2018 at 17:24
13

This does all the work in the database server. The result is a simple array.

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

Rails will generate SQL that works on any database (Postgres, MySQL, etc).

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

I suggest to use Product.all.distinct.pluck(:category) because uniq has been deprecated since rails 5 and it will be removed on rails 5.1

0
6

Try this (in the rails console)

Product.group(:category)

Product.group(:category).each { |p| p.name }
3
  • 5
    That will only work on MySql databases (possibly sqlite as well but definitely not good on Postgres or MSSQL
    – jamesc
    Commented May 18, 2012 at 16:59
  • Works on sqlite
    – Geoffrey H
    Commented Oct 5, 2016 at 13:19
  • You have to: Product.select(:category).group(:category) to get this to work on Postgresql (and I guess MSSQL). Commented Jun 10, 2019 at 19:17
5

For postgres

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

Update

even better

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

because it can return wrong columns when you do joins (e.g. returns id column from joined table, but not products)

1
  • Voted up because when you require the whole active record relation instead of plucked values array, this solution worked for me. Commented Apr 13, 2020 at 8:05
1

If you or anyone want to get two or more attributes from a table like products, based on a distinct feature of an attribute, only this solution will help you for Rails >= 5.1

distinct_products = Product.select("DISTINCT ON (category) *")

# it's an active record relation class.
> distinct_products.class
=> Product::ActiveRecord_Relation

N.B. Don't use .pluck() on the distinct_products. It will reselect from the products table and the distinct feature will not work anymore.

1

It's 2024 and I had to use Product.pluck(:category).uniq to get this to work in Rails 7.1.

None of the other solutions here worked for me.

0

Needed to get unique output and was trying the 'uniq' method unsuccessfully. Tried several solutions posted here unsuccessfully. I'm using devise which gives me access to the current_user method and working with two tables, one being a join (an item has_many :things).

This solution ultimately worked for me :

@current_user.things.select(:item_fk).distinct.each do |thing|
 <%= thing.item.attribute %>
<% end %>

Not the answer you're looking for? Browse other questions tagged or ask your own question.