Rails 使用活动记录复杂查询执行内部连接
Rails perform inner join with active record complex query
我必须执行复杂的活动记录查询。
我有 5 个模型
卡片模型
class Card < ActiveRecord::Base
has_many :leads
has_many :programs, through: :leads
end
潜在客户模型
class Lead < ActiveRecord::Base
belongs_to :card
belongs_to :program
end
程序模型
class Program < ActiveRecord::Base
has_many :leads
has_many :cards, through: :leads
belongs_to :school
end
学校模型
class School < ActiveRecord::Base
has_many :programs
belongs_to :representative
end
代表车型
class Representative < ActiveRecord::Base
has_many :schools
end
我想统计每个学校和每个代表有多少张卡片。一个代表有很多学校,一个学校有很多节目,一个节目有很多卡片。
我知道我必须执行内部联接,但经过一些研究后我还没有找到任何精确的说明。谢谢你的帮助。
为您的某些模型添加更多关联应该会有所帮助。
class School < ActiveRecord::Base
# in addition to existing relations
has_many :leads, through: :programs
has_many :cards, through: :leads
end
class Representative < ActiveRecord::Base
# in addition to existing relations
has_many :programs, through: :schools
has_many :leads, through: :programs
has_many :cards, through: :leads
end
那么,简单的获取单个学校或代表的卡片数量的方法应该很简单。
@school.cards.count
@representative.cards.count
如果您想获得唯一卡片的数量,即一张卡片可能与同一学校或代表内的多个项目相关联,并且您希望每个卡片只计算一次,请使用 distinct
.
@school.cards.distinct.count
@representative.cards.distinct.count
现在,如果您想获得每个学校和代表拥有的卡片数量,这有点棘手,但仍然有可能。
@schools = School.select('schools.*, count(cards.id)')
.joins(programs: { leads: :card } )
.group(:id)
@reps = Representative.select('representative.*, count(cards.id)')
.joins(schools: { programs: { leads: :card } } )
.group(:id)
如果您希望每所学校或代表的卡片数量唯一,只需在适当的查询中将 count(cards.id)
更改为 count(distinct cards.id)
。
关于这些解决方案的几点说明:
- 如果学校或代表有 零 张卡片,它们将不会出现在
@schools
和 @representatives
变量中。为了使它们出现,您需要稍微调整查询并使用 LEFT JOIN
.
- 您可能甚至不需要在
School
和 Representative
模型中关联到 :cards
来获得计数;您可能只使用 :leads
关联。但是,这会使区分变得更加困难,所以这就是我选择 :cards
. 的原因
我必须执行复杂的活动记录查询。
我有 5 个模型
卡片模型
class Card < ActiveRecord::Base
has_many :leads
has_many :programs, through: :leads
end
潜在客户模型
class Lead < ActiveRecord::Base
belongs_to :card
belongs_to :program
end
程序模型
class Program < ActiveRecord::Base
has_many :leads
has_many :cards, through: :leads
belongs_to :school
end
学校模型
class School < ActiveRecord::Base
has_many :programs
belongs_to :representative
end
代表车型
class Representative < ActiveRecord::Base
has_many :schools
end
我想统计每个学校和每个代表有多少张卡片。一个代表有很多学校,一个学校有很多节目,一个节目有很多卡片。
我知道我必须执行内部联接,但经过一些研究后我还没有找到任何精确的说明。谢谢你的帮助。
为您的某些模型添加更多关联应该会有所帮助。
class School < ActiveRecord::Base
# in addition to existing relations
has_many :leads, through: :programs
has_many :cards, through: :leads
end
class Representative < ActiveRecord::Base
# in addition to existing relations
has_many :programs, through: :schools
has_many :leads, through: :programs
has_many :cards, through: :leads
end
那么,简单的获取单个学校或代表的卡片数量的方法应该很简单。
@school.cards.count
@representative.cards.count
如果您想获得唯一卡片的数量,即一张卡片可能与同一学校或代表内的多个项目相关联,并且您希望每个卡片只计算一次,请使用 distinct
.
@school.cards.distinct.count
@representative.cards.distinct.count
现在,如果您想获得每个学校和代表拥有的卡片数量,这有点棘手,但仍然有可能。
@schools = School.select('schools.*, count(cards.id)')
.joins(programs: { leads: :card } )
.group(:id)
@reps = Representative.select('representative.*, count(cards.id)')
.joins(schools: { programs: { leads: :card } } )
.group(:id)
如果您希望每所学校或代表的卡片数量唯一,只需在适当的查询中将 count(cards.id)
更改为 count(distinct cards.id)
。
关于这些解决方案的几点说明:
- 如果学校或代表有 零 张卡片,它们将不会出现在
@schools
和@representatives
变量中。为了使它们出现,您需要稍微调整查询并使用LEFT JOIN
. - 您可能甚至不需要在
School
和Representative
模型中关联到:cards
来获得计数;您可能只使用:leads
关联。但是,这会使区分变得更加困难,所以这就是我选择:cards
. 的原因