J'ai déjà une solution qui fonctionne, mais j'aimerais vraiment savoir pourquoi cela ne fonctionne pas:
ratings = Model.select(:rating).uniq
ratings.each { |r| puts r.rating }
Il sélectionne, mais n'imprime pas de valeurs uniques, il imprime toutes les valeurs, y compris les doublons. Et c'est dans la documentation: http://guides.rubyonrails.org/active_record_querying.html#selecting-specific-fields
Model.select(:rating)
Le résultat est une collection d'objets Model
. Not notes simples. Et du point de vue de uniq
, ils sont complètement différents. Vous pouvez utiliser ceci:
Model.select(:rating).map(&:rating).uniq
ou ceci (le plus efficace)
Model.uniq.pluck(:rating)
# Rails 5+
Model.distinct.pluck(:rating)
Apparemment, à partir de Rails 5.0.0.1, cela ne fonctionne que sur les requêtes de "niveau supérieur", comme ci-dessus. Ne fonctionne pas sur les proxy de collection (relations "has_many", par exemple).
Address.distinct.pluck(:city) # => ['Moscow']
user.addresses.distinct.pluck(:city) # => ['Moscow', 'Moscow', 'Moscow']
Dans ce cas, dédupliquer après la requête
user.addresses.pluck(:city).uniq # => ['Moscow']
Si vous utilisez Model.select
, vous pouvez également utiliser DISTINCT
, car il ne renverra que les valeurs uniques. Cela est préférable car cela signifie qu'il renvoie moins de lignes et doit être légèrement plus rapide que de renvoyer un nombre de lignes puis de demander à Rails de choisir les valeurs uniques.
Model.select('DISTINCT rating')
Bien sûr, ceci est fourni si votre base de données comprend le mot clé DISTINCT
, et la plupart le devraient.
Cela fonctionne aussi.
Model.pluck("DISTINCT rating")
Model.uniq.pluck(:rating)
# SELECT DISTINCT "models"."rating" FROM "models"
Cela présente les avantages de ne pas utiliser de chaînes SQL et de ne pas instancier des modèles
Si vous souhaitez également sélectionner des champs supplémentaires:
Model.select('DISTINCT ON (models.ratings) models.ratings, models.id').map { |m| [m.id, m.ratings] }
Model.select(:rating).uniq
Ce code fonctionne comme 'DISTINCT' (pas comme Array # uniq) depuis Rails 3.2
Si je vais droit au chemin alors:
Requête en cours
Model.select(:rating)
renvoie un tableau d'objet et vous avez écrit une requête
Model.select(:rating).uniq
uniq est appliqué sur un tableau d'objet et chaque objet a un identifiant unique. uniq effectue correctement son travail car chaque objet du tableau est uniq.
Il y a plusieurs façons de sélectionner un classement distinct:
Model.select('distinct rating').map(&:rating)
ou
Model.select('distinct rating').collect(&:rating)
ou
Model.select(:rating).map(&:rating).uniq
ou
Model.select(:name).collect(&:rating).uniq
Une dernière chose, première et deuxième requête: trouvez des données distinctes par requête SQL.
Ces requêtes seront considérées comme "londres" et "londres", ce qui signifie qu'elles négligeront l'espace. C'est pourquoi il sélectionnera "Londres" une fois dans le résultat de votre requête.
Troisième et quatrième requête:
rechercher des données par requête SQL et pour appliquer des données distinctes Ruby uniq mehtod. ces requêtes seront considérées comme "londres" et "londres" différentes, c'est pourquoi il sélectionnera "londres" et "londres" dans le résultat de votre requête.
merci de préférer l’image attachée pour plus de compréhension et jeter un oeil sur "Appel d’offres en tournée/en attente".
Certaines réponses ne prennent pas en compte le PO veut un tableau de valeurs
Les autres réponses ne fonctionnent pas bien si votre modèle contient des milliers d'enregistrements.
Cela dit, je pense qu'une bonne réponse est:
Model.uniq.select(:ratings).map(&:ratings)
=> "SELECT DISTINCT ratings FROM `models` "
Parce que vous générez d’abord un tableau de Model (avec une taille réduite en raison de la sélection), vous extrayez ensuite le seul attribut que ces modèles sélectionnés ont (évaluations)
Si quelqu'un cherche la même chose avec Mongoid, c'est
Model.distinct(:rating)
Model.select(:rating).distinct
Une autre façon de collecter des colonnes uniques avec SQL:
Model.group(:rating).pluck(:rating)