PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Table join sql to rails active record query


Se você tiver uma associação entre Review e Audio então algo assim:
revs = Review.joins(:audios)
             .group('style_id')
             .select('style_id, avg(col1) as avg_col1, avg(col2) as avg_col2')

Isso fornecerá uma lista de Review instâncias em revs e essas instâncias terão avg_col1 extra e avg_col2 métodos para acessar as médias, bem como o habitual style /style_id métodos, mas os outros métodos de acesso de coluna que Review normalmente ofereceria levantará exceções.

Se você não tiver as associações configuradas, poderá fazer o JOIN manualmente:
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')

Se tudo o que você precisa é apenas dos dados brutos sem todo o encapsulamento e sobrecarga do ActiveRecord, você pode executar o SQL bruto e hashá-lo manualmente usando 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

Isso lhe daria um Array of Hashes. Você pode até simplificar essa abordagem usando Struct para criar classes simples de wrapper de dados:
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ão use condições de junção implícitas em seu SQL, essa é apenas uma maneira rápida e fácil de produzir produtos cruzados, use condições de junção explícitas:
SELECT ...
  FROM reviews JOIN audios ON reviews.consumer_id = audios.consumer_id
 GROUP BY style_id