如何将以下内容转换为活动记录查询:
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。
如何将以下内容转换为活动记录查询:
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')
这将给出一个Review
实例列表,revs
这些实例将具有额外的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 并使用以下方法手动对其进行哈希化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