2012-05-17 64 views
3

我如何轉換以下爲活動記錄查詢:表連接的SQL軌活動記錄查詢

SELECT reviews.style_id, AVG("col1"), AVG("col2") 
    FROM reviews, audios 
WHERE reviews.consumer_id = audios.consumer_id 
GROUP BY style_id; 

col1col2屬於音頻表,但他們唯一命名的(在沒有類似的列名reviews),所以沒有歧義錯誤。

我正在使用PostgreSQL。

+0

爲什麼轉換,執行它作爲一個原始的sql – beck03076

回答

6

如果你有ReviewAudio之間的關聯則是這樣的:

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

這將會給Review實例列表中revs和這些情況下,會得到額外avg_col1avg_col2方法訪問的平均值爲以及通常的style/style_id方法,但Review通常會提供的其他列存取方法會引發異常。

如果您沒有設置那麼協會可以做手工JOIN:

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

如果你需要的只是沒有所有的ActiveRecord的包裝和開銷的原始數據,那麼你可以執行原始SQL,並用手hashify它使用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 

這將使你哈希值的數組。

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:不要使用隱式連接條件的SQL,這只是以產生交叉產品快速簡便的方法,使用顯式連接條件,你甚至可以使用Struct創建簡單的數據包裝類簡化方法:

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

姆,你知道任何高級活動記錄查詢的好教程。我想了解更多。謝謝 – Abram

+1

@Abram:有[活動記錄查詢界面指南](http://guides.rubyonrails.org/active_record_querying.html),我不知道什麼比我的標題頂部更好。我使用了這個指南,並在Rails控制檯中玩了很多東西來學習這些東西;具有很強的SQL-fu當然有幫助。 –

+1

順便說一句,看起來活躍的記錄方法是.joins,而不是.join ..無論哪種方式,超級有用..我已經設法實現一些驚人的東西感謝您的帖子。歡呼聲 – Abram