gpt4 book ai didi

ruby-on-rails - 使用 Rails 4 Activerecord 将多个列计数合并到一个查询中

转载 作者:行者123 更新时间:2023-11-29 11:47:51 26 4
gpt4 key购买 nike

Rails 4.1,Postgres 9.3,部署到 Heroku

我正在尝试减少对数据库的调用次数。

我有一个大表,surveys,有多个 bool 列,如 role_composerrole_performer 等等。

Controller 有多个查询,例如

@sample = Survey.where(...whatever...)
@Composers = @sample.count("case when role_composer then true end")
...
@Performers = @sample.count("case when role_performer then true end")

这工作正常,但会导致对数据库的许多单独查询,这些查询仅在选择中的表达式不同。有没有办法将其构建为具有多个聚合/计算列的一个查询?我也有使用 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(... ) 作为 col2"])

提前感谢您的回答。

最佳答案

如果您记得两件事,您的 .select("count(...) as col1, count(...) as col2") 版本应该可以正常工作:

  1. M.where(...).select(...) 返回多项内容,即使查询仅返回一行也是如此。
  2. 仅仅因为某些东西没有出现在 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

这将为您提供一个 Surveycounts 实例。如果您在控制台中查看 counts,您会看到如下内容:

#<Survey > 

inspect 输出仅包括来自列的值(即 Survey 类知道的东西),但 composersperformers 会在那里。然而,由于 ActiveRecord 不知道它们应该是什么类型,它们将作为字符串输出:

composers  = counts.composers.to_i
performers = counts.performers.to_i

如果去寻找,您的select 中的所有内容都会在那里。

关于ruby-on-rails - 使用 Rails 4 Activerecord 将多个列计数合并到一个查询中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27494401/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com