我想找到courses
至少有variant
variant_type
= 1且variant
variant_type
= 2的Course.where("id IN ( SELECT course_id
FROM course_variants
WHERE variant_type = 1
)
AND id NOT IN (
SELECT course_id
FROM course_variants
WHERE variant_type = 2
)")
。
所以我的查询如下:
course
此外,course_variants
有许多course: {id=1, course_variants: [{variant_type: 1}, {variant_type: 2}]}
course: {id=2, course_variants: [{variant_type: 1}, {variant_type: 3}]}
course: {id=3, course_variants: [{variant_type: 2}, {variant_type: 3}]}
。
我在where子句中使用原始查询,我想使用Active记录接口或Arel来改进它,对此有什么解决方案吗?
谢谢!
输入
course: {id=2, course_variants: [{variant_type: 1}, {variant_type: 3}]}
输出
rake deploy
答案 0 :(得分:4)
您可以稍微调整您的模型关联:
class Course < ActiveRecord::Base
has_many :type_1_variants, class_name: "CourseVariant", -> { where(variant_type: 1) }
has_many :non_type_3_variants, class_name: "CourseVariant", -> { where.not(variant_type: 3) }
end
Course.joins(:type_1_variants, :non_type_3_variants).group(:course_id).having('COUNT(course_variants.id) > 0').having('COUNT(non_type_3_variants_courses.id) > 0')
您可能需要更换&#39; non_type_3_variants_courses&#39;使用ARel在进行连接时生成的正确别名(我没有Rails环境)
答案 1 :(得分:1)
您应该使用连接方法连接两个表courses
和course_variants
,然后在where方法中定义条件,如下所示:
Course.joins("INNER JOIN course_variants on courses.id = course_variants.course_id")
.where("course_variants.variant_type" => 1)
答案 2 :(得分:1)
试试这个:
Course.where(id: CourseVariant.where(variant_type: 1).pluck(:course_id)).where.not(id: CourseVariant.where(variant_type: 2).pluck(:course_id))
希望这有帮助。 :)
答案 3 :(得分:1)
嘿,你可以尝试这种方式,它是优化的方式来找到这样的记录,这里不需要两次火灾:
你可以在Rails中为第二个查询执行此操作:
Course.joins(:course_variants).where(:course_variants => {:variant_type => 1}).where("courses.id not in (?)",CourseVariant.where(:variant_type => 2).pluck(:course_id))
您可以在单个查询中使用内部查询,该查询比上述更快:
Course.joins(:course_variants).where(:course_variants => {:variant_type => 1}).where("courses.id not in (select course_id from course_variants where variant_type = 2)")
您可以在mysql的单个查询中使用group
执行此操作:
Course.joins(:course_variants).group("course_variants.course_id").having("SUM(CASE WHEN variant_type = 1 THEN 1
WHEN variant_type = 2 THEN 2
ELSE 0
END) = 1")
答案 4 :(得分:0)
如果您在Course和CourseVarint模型之间有关联,那么您可以执行以下操作:
Course.joins(:course_variants).where(course_variants: {variant_type: 1}).where.not(course_variants: {variant_type: 2})