[英]Table join sql to rails active record query
如何將以下內容轉換為活動記錄查詢:
SELECT reviews.style_id, AVG("col1"), AVG("col2")
FROM reviews, audios
WHERE reviews.consumer_id = audios.consumer_id
GROUP BY style_id;
col1
和col2
屬於audios表,但它們是唯一命名的( reviews
沒有類似的列名),因此沒有歧義錯誤。
我正在使用PostgreSQL。
如果您在Review
和Audio
之間有關聯,那么這樣的事情:
revs = Review.joins(:audios)
.group('style_id')
.select('style_id, avg(col1) as avg_col1, avg(col2) as avg_col2')
這將給出revs
中的Review
實例列表,這些實例將有額外的avg_col1
和avg_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
這會給你一個哈希數組。 您甚至可以使用Struct
簡化該方法來創建簡單的數據包裝類:
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中使用隱式連接條件,這只是生成交叉產品的一種快速簡便的方法,使用顯式連接條件:
SELECT ...
FROM reviews JOIN audios ON reviews.consumer_id = audios.consumer_id
GROUP BY style_id
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.