La question est pourquoi auriez-vous besoin d'une "requête imbriquée"? Nous n'avons pas besoin d'utiliser des "requêtes imbriquées" c'est penser dans l'état d'esprit de SQL non algèbre relationnelle. Avec l'algèbre relationnelle que nous tirons des relations et utiliser la sortie d'une relation en entrée à l'autre de sorte que le suivant serait vrai:
points = Table(:points, {:as => 'sorted'}) # rename in the options hash
final_points = points.order('timestamp DESC').group(:client_id, :timestamp).project(:client_id, :timestamp)
Il est préférable, si nous laissons le changement de nom à Arel, sauf nécessité absolue.
Ici, la projection de client_id ET timestamp est TRES importante car nous ne pouvons pas projeter tous les domaines de la relation (c'est-à-dire triés. *). Vous devez spécifiquement projeter tous les domaines qui seront utilisés dans l'opération de regroupement pour la relation. La raison en est qu'il n'y a pas de valeur pour * qui serait distinctement représentatif d'un id_client groupé. Par exemple que vous avez le tableau suivant
client_id | score
----------------------
4 | 27
3 | 35
2 | 22
4 | 69
ici si vous regroupez vous ne pouvez effectuer une projection sur le domaine de points parce que la valeur pourrait être soit 27 ou 69 mais vous pouvez projeter une somme (score)
Vous pouvez uniquement projeter les attributs de domaine ayant des valeurs uniques dans le groupe (qui sont généralement des fonctions d'agrégation telles que sum, max, min). Avec votre requête, peu importe si les points ont été triés par date et heure, car à la fin, ils seront groupés par client_id. l'ordre d'horodatage n'est pas pertinent car il n'y a pas d'horodatage unique qui pourrait représenter un regroupement.
S'il vous plaît laissez-moi savoir comment je peux vous aider avec Arel. Aussi, j'ai travaillé sur une série d'apprentissage pour que les gens utilisent Arel à la base. Le premier de la série est à http://Innovative-Studios.com/#pilot Je peux vous dire que vous commencez à savoir comment vous avez utilisé Table (: points) plutôt que le point modèle ActiveRecord.
Merci pour la réponse détaillée. "l'ordre d'horodatage n'est pas pertinent car il n'y a pas d'horodatage unique qui pourrait représenter un regroupement." Tu as raison; J'entends ce que vous dites. Il semble que MySQL contourne cette incohérence en renvoyant juste la première ligne du groupe client_id, ce que je visais. Je vois maintenant ce n'est pas un comportement sur lequel je devrais compter. Mon objectif est de renvoyer le point le plus récent pour tous les clients_ids, c'est-à-dire un seul point avec l'horodatage maximum pour chaque groupement client_id. Il est important de faire une requête car elle sera souvent interrogée. – Schrockwell
Nous aurions besoin d'utiliser une fonction d'agrégat. Si nous nous demandons "Qu'est-ce que nous essayons de faire?" La réponse serait de trouver la date la plus récente ou "maximum" afin que nous passions max (timestamp) en sql. Cela correspondrait à Arel :: Attribute :: Expression :: Maximum qui peut être appelé avec du sucre syntaxique sur un attribut Arel :: tel que trié [: timestamp] .maximum(). Il y a une mise en garde. Assurez-vous d'ajouter l'horodatage à l'opération de groupe #group ('client_id, horodatage') ou l'ensemble du scénario de regroupement produira une erreur. Je sais que la fonction d'agrégat MAX fonctionne sur les dates dans Postgres et j'en suis sûr aussi dans MySQL. – Snuggs
Premièrement, le tri et l'ordre ne font pas partie de l'algèbre relationnelle. Arel le définit quand même. Deuxièmement, que les sous-requêtes fassent ou non partie de l'algèbre relationnelle n'est pas pertinent. Conceptuellement, le résultat d'un SELECT n'est pas visible tant que la clause WHERE n'est pas exécutée. Par conséquent, toutes les bases de données (par exemple, Postgres) n'autorisent pas les alias de colonnes dans les clauses WHERE et dépendent plutôt des sous-requêtes. Si Arel ne peut pas gérer les sous-requêtes, les noms de la clause WHERE ne peuvent pas être aliasés. Cela peut devenir compliqué quand vous ne pouvez pas compter sur Arel pour générer des noms. –