簡體   English   中英

Ruby on Rails活動記錄查詢

[英]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"]]

...不過,它似乎確實得到了結果。


[英]#<ActiveRecord::AssociationRelation Active Record Query Ruby on Rails

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM