Rails 4.1,Postgres 9.3,部署到Heroku
我正在尝试减少对数据库的调用次数。
我有一个大表,调查,有多个布尔列,如role_composer
,role_performer
,等等。
控制器有多个查询,例如
@sample = Survey.where(...whatever...)
@Composers = @sample.count("case when role_composer then true end")
...
@Performers = @sample.count("case when role_performer then true end")
这样可以正常工作,但会导致对数据库的许多单独查询只有select中的表达式不同。有没有办法将此构造为具有多个聚合/计算列的一个查询?我也有使用average()和表达式的查询,但最常见的是count()。
在postgres中,这有效:
SELECT count(case when role_composer then true end) as "COMPOSERS", count(case when role_performer then true end) as "PERFORMERS" from surveys;
使用@sample上的Activerecord方法而不是求助于find_by_sql()的任何方法吗?
我尝试了多种方法但没有成功:.count().count()
,.count([array])
,.select("count(...) as col1, count(...) as col2")
,.select(["count(...) as col1", "count(...) as col2"])
提前感谢您的任何答案。
答案 0 :(得分:2)
如果你记得两件事,你的.select("count(...) as col1, count(...) as col2")
版本应该可以正常工作:
M.where(...).select(...)
也会返回多个内容。inspect
输出中没有出现某些内容并不意味着它不存在。您正在进行没有GROUP BY的聚合,因此您只能获得一行。要打开该行,您可以说first
:
counts = Survey.where(...)
.select('count(case when role_composer then true end) as composers, count(case when role_performer then true end) as performers')
.first
这会在Survey
中为您提供counts
个实例。如果你在控制台中查看counts
,你会看到如下内容:
#<Survey >
inspect
输出仅包含列中的值(即Survey
类知道的内容),但composers
和performers
将在那里。但是,由于ActiveRecord不知道它们应该是什么类型,它们将作为字符串出现:
composers = counts.composers.to_i
performers = counts.performers.to_i
如果去寻找,select
中的所有内容都会存在。