mysql - 一次查询 ActiveRecord 的记录和关系计算

标签 mysql ruby-on-rails ruby activerecord ruby-on-rails-4

TL;博士?见编辑 2

我有一个小的 Rails 应用程序,它有一些人们可以玩的不同类型的游戏:它基于体育,所以他们可以每周挑选每场比赛的获胜者(模型 PickEm ,属性 correct bool 值,未完成游戏的属性为 nil),并预测特定球队比赛的结果(模型 Guess ,属性 score 为整数,nil 为未完成的比赛)。每个 User has_many PickEmsGuesses 。而且我正在尝试显示排名( correct/total - total 都是非 nilscore/total 可能)。

我发现我可以收集用户及其相关记录,但在尝试显示排名时,我发现每个用户都在触发另一个查询 - 随着用户群的增加,速度缓慢且不可持续。那是因为 @user.pick_em_scorepick_ems.where(correct: true).size@user.guess_Scoreguesses.where.not(score: nil).sum(:score) 。所以我调用 user.pick_em_score 并运行该查询。我觉得应该有一种方法可以一次获取每个 User 以及这些特定计数,而不是缓冲一大堆不必要的额外内容。

我需要的:

  • User 记录
  • User.pick_em_score(计算correct条记录)
  • User.pick_ems 计数在哪里 NOT NULL
  • User.guesses_score(由guesses.sum(:score)计算)
  • User.guesses 计数在哪里 NOT NULL

  • 我在 Rails 的 ActiveRecord 助手中找到的大部分内容,尤其是与计算相关的内容,都是仅用于检索计算。看起来我可能需要直接深入研究 select() 等。但我无法让它工作。有人可以指出我正确的方向吗?

    编辑

    澄清一下:我知道我可以将此信息写入 User 模型,但这过于严格:下个赛季,我需要在 User 中添加一个新列以获取当年的结果等。此外,这个是第三级回调更新相关模型——Match 模型在保存时已经更新了相关的 PickEmsGuesses 我正在寻找最简单的 ActiveRecord 查询或能够处理此信息的查询,如标题所示。 理想情况下一个查询返回上述信息,但如果需要几个,那没关系。

    我以前使用 PHP 直接在 MySQL 中工作,但这些技能已经生锈了(我想,在原始 MySQL 中,我会有几个子选择语句来帮助提取这些计数),我也希望能够使用 Rails 的ActiveRecord 助手等,并尽可能避免构建原始 SQL。

    第二次编辑:

    我似乎把它归结为一个开始工作的调用,但我正在写很多 SQL。 它也很脆弱,IMO,尝试运行它失败了。看起来我只是将 Rails 中的百万个单数 SELECT 查询直接推送到 SQL 中,但这可能仍然是一个进步。

    User.unscoped.select('users.*',
      '(SELECT COUNT(*) FROM pick_ems WHERE pick_ems.user_id = users.id AND pick_ems.correct) AS correct_pick_ems',
      '(SELECT COUNT(*) FROM pick_ems WHERE pick_ems.user_id = users.id AND pick_ems.correct IS NOT NULL) AS total_pick_ems',
      '(SELECT SUM(guesses.score) FROM guesses WHERE guesses.user_id = users.id AND guesses.score IS NOT NULL) AS guesses_score',
      '(SELECT COUNT(*) FROM guesses WHERE guesses.user_id = users.id AND guesses.score IS NOT NULL) AS guesses_count' )
    

    问题似乎是: 有没有一种方法可以使用 Rails 而不是原始 SQL 来链接我们在那里看到的 users.id 和这些子查询 ?或者只是……一般来说是一种更好的构建方法?

    此外,我正在为 SELECT 运行另一组 WHERE ,这将取决于 total_pick_emsguesses_count> 0 但由于我不能使用这些别名列,我必须再调用一次 SELECT

    最佳答案

    欢迎来到 AR。它真的只适用于简单的 CRUD 之类的查询。一旦您真的想愤怒地查询您的数据,它就没有能力执行您想要的查询,而无需求助于批发 SQL 字符串,因此通常会放弃链接的能力。

    这正是我转向 Sequel 的原因,因为它确实具有使用更完整的 SQL 功能集组合查询的功能,包括连接条件、窗口函数、递归公用表表达式和高级预加载。与 AR 和 Arel 相比,作者 react 迅速,文档也非常出色。

    我不希望您会喜欢这个答案,但总有一天,您会开始关注带有 rails 的自以为是的组件,我不得不说这些组件几乎不是同类产品中最好的。 Sequel 还使我的应用程序速度比我使用 AR 能够获得的速度快很多倍,这不仅是开发人员的快乐,还意味着可以运行的服务器更少。是的,这将是一个学习曲线,但 IMO 最好学习有你支持的工具。

    关于mysql - 一次查询 ActiveRecord 的记录和关系计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26577573/

    相关文章:

    PHP MySQL - 需要显示文件列表及其文件大小、格式。重新声明函数错误

    php - xampp 控制面板 Apache 端口未打开

    php - 在 Laravel 中的大型表上创建模型时创建唯一的跟踪代码

    ruby-on-rails - :dependency => :destroy not working as planned?

    html - 如果选中复选框,如何更改索引中的字体颜色?

    php - 从搜索栏中的用户输入中删除单引号

    ruby-on-rails - 事件记录存储删除

    javascript - 将单个对象加载到 sencha touch 中的数据存储中

    Mysql日期和rails日期与UTC

    ruby - 替换非单词字符,除非给定的序列匹配