PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Table join sql to rails active record query

Si vous avez une association entre Review et Audio puis quelque chose comme ça :

revs = Review.joins(:audios)
             .group('style_id')
             .select('style_id, avg(col1) as avg_col1, avg(col2) as avg_col2')

Cela donnera une liste de Review instances en revs et ces instances auront un avg_col1 supplémentaire et avg_col2 les méthodes d'accès aux moyennes ainsi que le style habituel /style_id méthodes mais les autres méthodes d'accès aux colonnes que Review offrirait normalement soulèvera des exceptions.

Si vous n'avez pas configuré les associations, vous pouvez effectuer le JOIN manuellement :

revs = Review.joins('join audios on reviews.consumer_id = audios.consumer_id')
             .group('style_id')
             .select('style_id, avg(col1) as avg_col1, avg(col2) as avg_col2')

Si vous n'avez besoin que des données brutes sans tout l'habillage et la surcharge d'ActiveRecord, vous pouvez alors exécuter le SQL brut et le hacher manuellement en utilisant select_rows :

Review.connection.select_rows(%q{
    select r.style_id, avg(a.col1), avg(a.col2')
    from reviews r
    join audios  a on r.consumer_id = a.consumer_id
    group by r.style_id
}).map do
  { :style_id => r.shift, :avg_col1 => r.shift.to_f, :avg_col2 => r.shift.to_f }
end

Cela vous donnerait un tableau de hachages. Vous pouvez même simplifier cette approche en utilisant Struct pour créer des classes wrapper de données simples :

c    = Struct.new(:style_id, :avg_col1, :avg_col2)
revs = Review.connection.select_rows(%q{...}).map do |r|
  c.new(r.shift, r.shift.to_f, r.shift.to_f)
end

PS :N'utilisez pas de conditions de jointure implicites dans votre SQL, c'est juste un moyen simple et rapide de produire des produits croisés, utilisez des conditions de jointure explicites :

SELECT ...
  FROM reviews JOIN audios ON reviews.consumer_id = audios.consumer_id
 GROUP BY style_id