左连接没有返回正确的信息

时间:2018-05-27 06:57:24

标签: mysql sql activerecord

我有一张表courses和一张表volunteer_rosterscourses包含所有课程的列表,volunteer_rosters包含教授/协助课程的志愿者列表。

我想写一个查询,该查询返回所有课程的列表,其中包含任何志愿者。这就是发生的事情:

courses     
-------     
id 
 1  
 3  
 4  
 5  
 6  

volunteer_courses
-----------------
id 1 course_id 1  
id 2 course_id 1  
id 3 course_id 1  
id 5 course_id 3  
id 6 course_id 3  

以下所有查询都返回了 course_id 3
course_id 4
course_id 5

为什么course_id 1(正确)被省略,但course_id 3不是???

Course.joins("LEFT JOIN student_rosters ON courses.id = student_rosters.course_id where student_rosters.course_id is null")

Course.joins("LEFT JOIN student_rosters ON courses.id = student_rosters.course_id").where(student_rosters: {id: nil})

Course.includes(:student_rosters).references(:student_rosters).where(student_rosters: {id: nil})

Course.includes(:student_rosters).references(:student_rosters).where('student_rosters.id = ?', nil)

Course.joins("LEFT JOIN student_rosters ON courses.id = student_rosters.course_id").where(student_rosters: {id: nil})

同样的问题,但没有一个解决方案适合我:

LEFT OUTER JOIN in Rails 4

2 个答案:

答案 0 :(得分:2)

无需使用join。试试这个:

select id from Courses
where id not in (select course_id from volunteer_courses)

答案 1 :(得分:0)

虽然不需要使用join,但使用not in对子查询很危险。它没有做你真正想要的。如果子查询中的任何行返回NULL值,则外部查询不返回任何内容。根本没有行。

出于这个原因,我强烈建议您使用not exists并避免not in子查询:

select c.id
from Courses c
where not exists (select 1 from volunteer_courses vc where vc.course_id = c.id);

left join版本:

select c.id
from Courses c left join
     volunteer_courses vc 
     on vc.course_id = c.id
where vc.course_id is null;

此外,这两个都可以利用volunteer_courses(course_id)上的索引。