sql - 使用 Active Record 的复杂 Ruby SQL 查询 - WHERE 使用 OR 子句和子查询

标签 sql ruby activerecord

我正在使用 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/

相关文章:

ruby-on-rails - 安装 rails 问题

ruby-on-rails - ActiveRecord 外键中使用的字符串主键

java - 此处不允许列 oracle 与 getText

SQL 将多行合并为多列

ruby - 在创建 Git 客户端 'commit-msg' Hook 方面需要帮助

ruby-on-rails - 如何在 Ruby 中逐行将文本文件从网站导入数据库

ruby-on-rails - 如何在 activerecord 之外创建 activerecord 样式验证?

ruby-on-rails - 通过关联查询 ActiveRecord

SQL JOIN 多个表并获取 AVG

sql - 左连接和右表中的数据