使用Rails 4 Activerecord将多个列计数合并到单个查询中
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()
.select("count(...) as col1, count(...) as col2")
.count([array])
.select("count(...) as col1, count(...) as col2")
.select(["count(...) as col1", "count(...) as col2"])
提前感谢您的任何答案。
如果你记住两件事.select("count(...) as col1, count(...) as col2")
你的.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
这将为您提供counts
的Survey
实例。 如果你在控制台中查看这些counts
,你会看到如下内容:
#
inspect
输出仅包含列中的值(即Survey
类知道的内容),但composers
和performers
将在那里。 但是,由于ActiveRecord不知道它们应该是什么类型,它们将作为字符串:
composers = counts.composers.to_i performers = counts.performers.to_i
如果去寻找它,你select
所有东西都会在那里。