2014-10-02 48 views
3

我正在使用Ruby 2.0.0和Rails 4.1.0。使用活動記錄的複雜Ruby SQL查詢 - 使用OR子句和子查詢的WHERE

我在努力將複雜的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中編寫?

有什麼想法?

謝謝!

***更新:

謝謝德魯,這工作!

我試圖讓它更漂亮,紅寶石般的基於以前的響應,所以我也

@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 - 未定義的方法'或」。我想這是一個依賴於arel的方法(​​),但我不想添加這個庫來解決OR問題。 SQL混合效果很好。謝謝!!

回答

0

以下情況如何?

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)