我正在使用 Ruby 2.0.0 和 Rails 4.1.0。
我正在努力将复杂的 SQL 查询转换为 Ruby。我能够转换其中的大部分内容,但我在使用“OR”子句时遇到了困难。
这是原始的 SQL 查询:
SELECT DISTINCT "lecture_classes".*
FROM "lecture_classes"
INNER JOIN
"lectures" ON "lectures"."id" = "lecture_classes"."lecture_id"
INNER JOIN
"weeks" ON "weeks"."id" = "lectures"."week_id"
WHERE "lectures"."part" = 1
AND "weeks"."number" = 1
AND "weeks"."course_id" = 1
AND( --very important parenthesis start
"lecture_classes"."id" IN (
SELECT "lecture_enrollments"."lecture_class_id"
FROM "lecture_enrollments"
GROUP BY lecture_class_id
HAVING count(lecture_class_id) <= 5
)
OR "lecture_classes"."id" --this is the OR that needs to have Ruby equivalent
NOT IN (
SELECT "lecture_enrollments"."lecture_class_id"
FROM "lecture_enrollments"
)
) --very important parenthesis ends
ORDER BY "lecture_classes"."class_date" ASC
我能够转换其中的大部分内容:
@max_students = 5
LectureClass
.joins(:lecture, lecture: :week)
.where(lectures: {part: part})
.where(weeks: {number: week, course_id: course})
.where(id: LectureEnrollment
.select("lecture_class_id")
.group("lecture_class_id")
.having("count(lecture_class_id) <= ?",@max_students)
)
.distinct
.order(class_date: :asc)
但我最大的困难是包含“OR”子句……并注意它需要与另一个子句一起放在括号内(在评论中注明),否则结果是错误的。
我知道我可以做类似的事情
Project.where("manager_user_id = ? OR account_manager = ?", current_user.id, current_user.id)
但我的问题是我没有 OR 值,它是 select 语句的结果。如何用 Ruby 编写?
有什么想法吗?
谢谢!
*** 更新:
谢谢德鲁,成功了!
根据您之前的回复,我试图让它更漂亮,更像 Ruby,所以我做到了
@max_students = 5
LectureClass
.joins(:lecture, lecture: :week)
.where(lectures: {part: part})
.where(weeks: {number: week, course_id: course})
.where(id: LectureEnrollment
.select("lecture_class_id")
.group("lecture_class_id")
.having("count(lecture_class_id) <= ?",@max_students)
)
.or( LectureClass
.where
.not(id:[LectureEnrollment
.select(:lecture_class_id)
])
)
.distinct
.order(class_date: :asc)
但是我收到一条错误消息 NoMethodError - undefined method `or'。我猜这是一个依赖于 arel 的方法(https://github.com/rails/arel),但我不想添加这个库只是为了解决 OR 问题。 SQL 组合效果很好。谢谢!!
最佳答案
下面的呢?
LectureClass
.joins(:lecture, lecture: :week)
.where(lectures: {part: part})
.where(weeks: {number: week, course_id: course})
.where("lecture_classes.id IN (
SELECT lecture_class_id
FROM lecture_enrollments
GROUP BY lecture_class_id
HAVING count(lecture_class_id) <= ?
)
OR lecture_classesid
NOT IN (
SELECT lecture_class_id
FROM lecture_enrollments
)", @max_students)
.distinct
.order(class_date: :asc)
关于sql - 使用 Active Record 的复杂 Ruby SQL 查询 - WHERE 使用 OR 子句和子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26168083/