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
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']
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.
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")
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
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
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] }
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)
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".
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)
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
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)
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