2013-11-25 77 views
46

我正在嘗試做一些我認爲它會很簡單但看起來沒有的事情。查找關聯數大於零的所有記錄

我有一個項目模型,有很多空缺。

class Project < ActiveRecord::Base 

    has_many :vacancies, :dependent => :destroy 

end 

我想獲得所有至少有一個空缺的項目。 我想是這樣的:

Project.joins(:vacancies).where('count(vacancies) > 0') 

但它說

SQLite3::SQLException: no such column: vacancies: SELECT "projects".* FROM "projects" INNER JOIN "vacancies" ON "vacancies"."project_id" = "projects"."id" WHERE ("projects"."deleted_at" IS NULL) AND (count(vacancies) > 0)

回答

29

joins默認使用內部連接,以便使用效果Project.joins(:vacancies)只會返回具有相關聯的空缺項目。

UPDATE:

正如在評論@mackskatz指出,沒有一個group條款,上面的代碼將返回項目重複的項目不止一個空缺。要刪除重複項,請使用

Project.joins(:vacancies).group('projects.id') 
+0

但是,如果不應用group by子句,則會返回具有多個空缺的項目的多個Project對象。 – mackshkatz

19

是的,vacancies不是連接中的字段。我相信你想要的:

Project.joins(:vacancies).group("projects.id").having("count(vacancies.id)>0") 
+0

哪裏有:假期從哪裏來? –

-4

錯誤是告訴你,空位基本上不是項目中的列。

這應該工作

Project.joins(:vacancies).where('COUNT(vacancies.project_id) > 0') 
+4

'WHERE'中不允許聚合函數 – squixy

87

1)要獲得項目至少有1空缺:

Project.joins(:vacancies).group('projects.id') 

2)爲了獲得項目,超過1個空缺:

Project.joins(:vacancies).group('projects.id').having('count(project_id) > 1') 

3)或者,如果Vacancy模型組計數器緩存:

belongs_to :project, counter_cache: true 

那麼這將工作,太:

Project.where('vacancies_count > ?', 1) 

vacancy拐點規則可能需要specified manually

2
# None 
Project.joins(:vacancies).group('projects.id').having('count(vacancies) = 0') 
# Any 
Project.joins(:vacancies).group('projects.id').having('count(vacancies) > 0') 
# One 
Project.joins(:vacancies).group('projects.id').having('count(vacancies) = 1') 
# More than 1 
Project.joins(:vacancies).group('projects.id').having('count(vacancies) > 1') 
0

沒有太多的Rails的魔術,你可以這樣做:

Project.where('(SELECT COUNT(*) FROM vacancies WHERE vacancies.project_id = projects.id) > 0') 

這種類型的條件將在所有的Rails版本的許多工作是工作,直接在數據庫端完成。另外,鏈接.count方法也可以很好地工作。之前,我被Project.joins(:vacancies)等查詢燒燬。當然,這有利有弊,因爲它不是數據庫不可知論者。

+0

這比join和group方法慢得多,因爲'select count(*)..'子查詢將針對每個項目執行。 – YasirAzgar

相關問題