Rails: wybierz unikalne wartości z kolumny

Mam już działające rozwiązanie, ale naprawdę chciałbym wiedzieć, dlaczego to nie działa:

ratings = Model.select(:rating).uniq
ratings.each { |r| puts r.rating }

Wybiera, ale nie wypisuje unikalnych wartości, wypisuje wszystkie wartości, łącznie z duplikatami. I jest w dokumentacji: http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields

Author: alexandrecosta, 2012-03-12

11 answers

Model.select(:rating)

Wynikiem tego jest zbiór Model obiektów. Nie zwykłe oceny. I z punktu widzenia uniq są zupełnie inne. Możesz użyć tego:

Model.select(:rating).map(&:rating).uniq

Lub to (najskuteczniejsze)

Model.uniq.pluck(:rating)

# rails 5+
Model.distinct.pluck(:rating)

Update

Najwyraźniej, od rails 5.0.0.1, działa tylko na zapytaniach "najwyższego poziomu", jak wyżej. Nie działa na serwerach proxy kolekcji (na przykład relacje" has_many").

Address.distinct.pluck(:city) # => ['Moscow']
user.addresses.distinct.pluck(:city) # => ['Moscow', 'Moscow', 'Moscow']

W tym przypadku deduplikuj po zapytaniu

user.addresses.pluck(:city).uniq # => ['Moscow']
 386
Author: Sergio Tulentsev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-14 04:51:47

Jeśli zamierzasz użyć Model.select, możesz równie dobrze użyć DISTINCT, ponieważ zwróci tylko unikalne wartości. Jest to lepsze, ponieważ oznacza, że zwraca mniej wierszy i powinno być nieco szybsze niż zwrócenie kilku wierszy, a następnie polecenie Rails, aby wybrał unikalne wartości.

Model.select('DISTINCT rating')

Oczywiście jest to pod warunkiem, że Twoja baza danych rozumie słowo kluczowe DISTINCT, a większość powinna.

 81
Author: kakubei,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-04 19:46:31

To też działa.

Model.pluck("DISTINCT rating")
 51
Author: Nat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-25 12:05:52
Model.uniq.pluck(:rating)

# SELECT DISTINCT "models"."rating" FROM "models"

Ma to tę zaletę, że nie używa ciągów sql i nie tworzy modeli instancji

 24
Author: Cameron Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-19 18:34:16
Model.select(:rating).uniq

Ten kod działa jako 'DISTINCT' (nie jako Array#uniq) od rails 3.2

 20
Author: kuboon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-04 06:49:35

Jeśli chcesz również wybrać dodatkowe pola:

Model.select('DISTINCT ON (models.ratings) models.ratings, models.id').map { |m| [m.id, m.ratings] }
 18
Author: Marcin Nowicki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-05 09:47:09

Jeśli ktoś szuka tego samego z Mongoidem, to jest

Model.distinct(:rating)
 4
Author: Vassilis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-08 00:12:49

If I am going right to way then:

Zapytanie bieżące

Model.select(:rating)

Zwraca tablicę obiektów i napisałeś zapytanie

Model.select(:rating).uniq

Uniq jest stosowane na tablicy obiektów i każdy obiekt ma unikalny identyfikator. uniq wykonuje swoje zadanie poprawnie, ponieważ każdy obiekt w tablicy jest uniq.

Istnieje wiele sposobów na wybranie odrębnej oceny:

Model.select('distinct rating').map(&:rating)

Lub

Model.select('distinct rating').collect(&:rating)

Lub

Model.select(:rating).map(&:rating).uniq

Lub

Model.select(:name).collect(&:rating).uniq

Jeszcze jedno, pierwsze i drugie zapytanie: znajdź różne dane za pomocą zapytania SQL.

Te zapytania będą uważane za "Londyn" i "Londyn" w ten sam sposób, że zaniedbają przestrzeń, dlatego wybierze "Londyn" jeden raz w wyniku zapytania.

Trzecie i czwarte zapytanie:

Find data by SQL query and for distinct data applied ruby uniq mehtod. zapytania te będą uważane za" Londyn "i" Londyn " różne, dlatego wybierze "Londyn" i "Londyn" zarówno w wyniku zapytania.

Proszę preferować załączony obraz, Aby uzyskać więcej zrozumienie i spojrzenie na "Toured / Waiting RFP".

Tutaj wpisz opis obrazka

 4
Author: uma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-12 19:04:53

Niektóre odpowiedzi nie uwzględniają tablicy wartości

Inne odpowiedzi nie działają dobrze, jeśli twój Model ma tysiące rekordów

To powiedziawszy, myślę, że dobra odpowiedź brzmi:

    Model.uniq.select(:ratings).map(&:ratings)
    => "SELECT DISTINCT ratings FROM `models` " 

Ponieważ najpierw generujesz tablicę modelu (o zmniejszonym rozmiarze z powodu wyboru), następnie wyodrębniasz jedyny atrybut, który mają wybrane modele (oceny)

 3
Author: Fernando Fabreti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-25 13:04:04
Model.select(:rating).distinct
 1
Author: hassan_i,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-16 14:22:20

Inny sposób zbierania kolumn uniq za pomocą sql:

Model.group(:rating).pluck(:rating)
 0
Author: Vyacheslav Zharkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-09 14:34:18