PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Tabellenverknüpfung sql to rails aktive Datensatzabfrage

Wenn Sie eine Verbindung zwischen Review haben und Audio dann etwa so:

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

Das ergibt eine Liste von Review Instanzen in revs und diese Instanzen haben zusätzliche avg_col1 und avg_col2 Methoden für den Zugriff auf die Durchschnittswerte sowie den üblichen style /style_id Methoden, aber die anderen Spaltenzugriffsmethoden, die Review normalerweise anbieten würde, wird Ausnahmen auslösen.

Wenn Sie die Zuordnungen nicht eingerichtet haben, können Sie den JOIN manuell durchführen:

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')

Wenn Sie nur die Rohdaten ohne ActiveRecord-Wrapping und Overhead benötigen, können Sie das Roh-SQL ausführen und per Hand mit 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

Das würde Ihnen ein Array von Hashes geben. Sie könnten diesen Ansatz sogar vereinfachen, indem Sie Struct verwenden um einfache Data-Wrapper-Klassen zu erstellen:

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:Verwenden Sie keine impliziten Join-Bedingungen in Ihrem SQL, das ist nur eine schnelle und einfache Möglichkeit, Kreuzprodukte zu erzeugen, verwenden Sie explizite Join-Bedingungen:

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