ruby-on-rails - 在 WHERE 中重构具有两个子选择的查询

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

我在项目模型上有以下范围,以查找至少已完成 80 项众筹 promise 的项目或已经达到目标的项目:

class Project < ActiveRecord::Base
  scope :popular, -> { collecting.where("80 <= (?) OR goal <= (?)",
    Pledge.select('COUNT(*)').where("project_id = projects.id").where(paid: true),
    Pledge.select('SUM(amount)').where("project_id = projects.id").where(paid: true))
  }

  (...)
end

这工作得很好,并为 Postres 生成以下 SQL:

Project.popular
# SELECT "projects".* FROM "projects"  WHERE "projects"."state" = 'collecting' AND (80 <= (SELECT COUNT(*) FROM "pledges"  WHERE (project_id = projects.id) AND "pledges"."paid" = 't') OR goal <= (SELECT SUM(amount) FROM "pledges"  WHERE (project_id = projects.id) AND "pledges"."paid" = 't'))

获取计数也很重要:

Project.popular.count
# SELECT COUNT(*) FROM "projects" WHERE "projects"."state" = 'collecting' AND (80 <= (SELECT COUNT(*) FROM "pledges" WHERE (project_id = projects.id) AND "pledges"."paid" = 't') OR goal <= (SELECT SUM(amount) FROM "pledges" WHERE (project_id = projects.id) AND "pledges"."paid" = 't'))

好的,子选择很好,但我觉得有更好、更有效的方法来做到这一点。我已经尝试过 joinssum,但是使用聚合函数的强制性 group 会破坏 Project.popular.count .

有什么重构方法吗?也许只是一种以哈希表示法执行 where("project_id = projects.id") 的方法?

最佳答案

我不知道这对你是否有好处,因为我无法用 ActiveRecord 行话表达下面的查询,但如果你可以,这将比当前生成的糟糕查询有很大改进

select "projects".*, project_count, project_amount
from
    "projects"
    inner join (
        select
            id,
            count(*) as project_count,
            sum(amount) as project_amount
        from pledges
        group by id
        where paid
    ) pledges using (id)
where
    "projects"."state" = 'collecting'
    and
    (project_count >= 80 or project_amount >= goal)

关于ruby-on-rails - 在 WHERE 中重构具有两个子选择的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24578358/

相关文章:

ruby-on-rails - Rails 3,@font-face 在使用 Firefox 的生产中失败

java - 在表或类似的表中使用两个主键

ruby-on-rails - 如何回滚Rails保存/交易?

ruby-on-rails - 使用单例类动态覆盖/添加 ActiveRecord 关联

ruby-on-rails - 为什么这些默认参数按原样定义?

ruby-on-rails - 在 Rails 3 中将 session 从 cookie_store 迁移到 Redis

ruby-on-rails - 如何使用Nginx/Passenger服务多个站点?

java - 高效的SQl查询获得用户喜爱

postgresql - Grails 3.3.x 似乎不支持 PostgreSQL 的 schema-per-tenant

ruby-on-rails - Rails find_or_create_by 带/不带哪里