簡體   English   中英

表連接sql到rails活動記錄查詢

[英]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;

col1col2屬於audios表,但它們是唯一命名的( reviews沒有類似的列名),因此沒有歧義錯誤。

我正在使用PostgreSQL。

如果您在ReviewAudio之間有關聯,那么這樣的事情:

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

這將給出revs中的Review實例列表,這些實例將有額外的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

這會給你一個哈希數組。 您甚至可以使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM