雇主和工作。雇主有很多工作。乔布斯有一个布尔字段。
我正在尝试查询并查找有多个已启动作业的雇主的计数。
我该怎么做?
Employer.first.jobs.where(已启动:true).count
我是否使用带计数器的循环,或者我是否可以使用查询进行循环?
谢谢!
答案 0 :(得分:1)
您可以加入条件
Employer.joins(:jobs).where(jobs: {started: true}).count
答案 1 :(得分:1)
您可以在Employer
模型中创建这样的范围:
def self.with_started_job
joins(:jobs)
.where(jobs: { started: true })
.having('COUNT(jobs.id) > 0')
end
然后,为了获得已经开始工作的雇主数量,您可以使用Employer.with_started_job.count
。
答案 2 :(得分:1)
缺少的是group by子句。使用.group()
然后count
。像
Employer.select("employers.id,count(*)").joins(:jobs).where("jobs.started = 1").group("employers.id")
这样的东西
查询连接两个表,消除了错误的记录,然后计算每个雇员的总记录数.id组合在一起。
答案 3 :(得分:0)
鉴于我不太熟悉SQL,我这样做的方式可能不是最佳的。我没有使用子查询就无法使用两个聚合。所以我将任务分成两部分:
当然,所有这些都在数据库级别上!没有原始SQL,所以在这里和那里使用Arel。以下是我的想法:
class Employer < ActiveRecord::Base
has_many :jobs
# I explored my possibilities using this method: fetches
# all the employers and number of jobs each has started.
# Looks best> Employer.with_started_job_counts.map(&:attributes)
# In the final method this one is not used, it's just handy.
def self.with_started_job_counts
jobs = Job.arel_table
joins(:jobs).select(arel_table[Arel.star],
jobs[:id].count.as('job_count'))
.merge(Job.where(started: true))
.group(:id)
end
# Alright. Now try to apply it. Seems to work alright.
def self.busy
jobs = Job.arel_table
joins(:jobs).merge(Job.where(started: true))
.group(:id)
.having(jobs[:id].count.gt 1)
end
# This is one of the tricks I've learned while fiddling
# with Arel. Counts any relations on the database level.
def self.generic_count(subquery)
from(subquery).count
end
# So now... we get this.
def self.busy_count
generic_count(busy)
end
# ...and it seems to get what we need!
end
结果SQL很大。不是很大,但你可能不得不用它解决性能问题。
SELECT COUNT(*)
FROM (
SELECT "employers".*
FROM "employers"
INNER JOIN "jobs" ON "jobs"."employer_id" = "employers"."id"
WHERE "jobs"."started" = ?
GROUP BY "employers"."id"
HAVING COUNT("jobs"."id") > 1
) subquery [["started", "t"]]
......但是,它似乎确实得到了结果。