【发布时间】:2019-07-19 17:44:15
【问题描述】:
我有以下型号:
# contributor.rb
class Contributor < ApplicationRecord
has_many :skill_groupings
has_many :skills, through: :skill_groupings
end
# skill_grouping.rb
class SkillGrouping < ApplicationRecord
belongs_to :skill
belongs_to :contributor
end
# skill.rb
class Skill < ApplicationRecord
has_many :skill_groupings
has_many :contributors, through: :skill_groupings
end
我想搜索(SQL 查询)其技能 ID 包含所有数组中包含的值的贡献者。
假设数据如下:
contributor_1.skill_ids: [2, 3, 6, 7]
contributor_2.skill_ids: [4, 7]
contributor_3.skill_ids: [9]
contributor_4.skill_ids: []
wanted_ids = [3, 7]
Contributor.joins(:skill_groupings).where(skill_groupings: { skill_id: wanted_ids }).distinct 返回技能 ID 中有 3 个或 7 的贡献者,因此是[contributor_1, contributor_2]。这不是我想要的。
查询的结果应该是[contributor_1],因为只有contributor_1拥有wanted_ids中的所有技能ID。
很遗憾,skill_ids 似乎只是 Rails 引入的一个属性,在 SQL 中不可用。
我怎样才能仅通过 SQL 查询来实现这一点?
【问题讨论】:
-
Contributor.where(id: Contributor.select(:id).joins(:skills).where(skills: { id: wanted_ids }).group(:id).having("COUNT(skills.id) = #{wanted_ids.uniq.size}"))对你有用吗 -
@engineersmnky 是的,谢谢,但这不是太长太麻烦了吗?是否存在更简单的查询?
-
IMO 这是实现您想要做的最简单的方法,这就是我在纯 SQL 中的处理方式(这会更长)。由于这是 postgres,因此以下内容应该可以工作并将其缩短一点
Contributor.joins(:skills).where(skills: { id: wanted_ids }).group(:id).having("COUNT(skills.id) = #{wanted_ids.uniq.size}"))。这是因为 postgres 允许您在返回所有列的同时按标识列分组(在大多数其他 SQL 数据库中不起作用) -
@engineersmnky 如果你写你的评论作为答案,我会接受它
标签: sql ruby-on-rails postgresql