[英]Ruby on Rails Active Record Query
雇主和工作。 雇主有很多工作。 作業已啟動一個布爾字段。
我正在嘗試查詢並查找已開始一項以上工作的雇主的計數。
我該怎么做呢?
Employer.first.jobs.where(started:true).count
我使用帶有計數器的循環還是可以通過查詢實現?
謝謝!
您可以有加入條件
Employer.joins(:jobs).where(jobs: {started: true}).count
您可以在Employer
模型中創建如下范圍:
def self.with_started_job
joins(:jobs)
.where(jobs: { started: true })
.having('COUNT(jobs.id) > 0')
end
然后,要獲取已開始工作的雇主數量,您可以使用Employer.with_started_job.count
。
缺少的是group by子句。 使用.group()
然后count
。 就像是
Employer.select("employers.id,count(*)").joins(:jobs).where("jobs.started = 1").group("employers.id")
該查詢將兩個表連接在一起,消除了錯誤的記錄,然后將每個loyer.id組合在一起時對總數的記錄進行計數。
考慮到我不太了解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"]]
...不過,它似乎確實得到了結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.