MySQL - 使用左连接来获取未分配资源的复杂查询

时间:2014-07-15 16:13:00

标签: mysql left-join

我有以下小提琴http://sqlfiddle.com/#!2/5c089/2

这是数据库表的架构:

id
school_id

classes_academic_years

id
class_id
name
academic_year_id
grade

classes_subjects

id
class_academic_year_id
subject_id

class_masters

id
class_academic_year_id
professor_id

教授

id
school_id
first_name
last_name

professors_subjects

id
professor_id
subject_id

professors_classes_subjects

id
professor_id
class_academic_year_id
subject_id

受试者

id
name
school_id
default

我有两个问题:

select subjects.* from subjects
inner join professors_subjects on professors_subjects.subject_id = subjects.id
where professors_subjects.professor_id = 198;

SELECT DISTINCT `subjects`.* 
FROM `subjects` 
INNER JOIN `classes_subjects` ON classes_subjects.subject_id = subjects.id 
INNER JOIN `classes_academic_years` ON classes_academic_years.id = classes_subjects.class_academic_year_id 
LEFT JOIN `professors_classes_subjects` ON professors_classes_subjects.class_academic_year_id = classes_subjects.class_academic_year_id and professors_classes_subjects.subject_id = classes_subjects.subject_id 
left join `class_masters` on class_masters.class_academic_year_id = classes_academic_years.id
WHERE ((professors_classes_subjects.id is null or professors_classes_subjects.professor_id = 198) and class_masters.professor_id = 198 ) 
AND (classes_academic_years.academic_year_id = 3) 
AND (subjects.default = 0) 
ORDER BY `name` asc;

第一个简单地取出分配给某位教授的所有科目(professor_id = 198)。

第二个将所有分配给某个教授的教授(professor_id = 198)提取给教授是班主任的班级,以及该班级中未分配给任何其他教授的所有科目。 (例如,professor_id = 198为class_id = 426分配了subject_id = 67,但是还有两个来自该类的未分配主题必须被提取)。

在给定的示例中,第一个查询获取ID为76和67的主题,第二个查询获取ID为86,72和67的主题。

这两个查询都运行得很好。但是,我需要第三个查询来组合这两个(例如,它应该获取具有ID 76,67,86和72的主题)。我更喜欢使用左连接,因此避免使用UNION操作符。

您对第三个查询有什么想法吗?

1 个答案:

答案 0 :(得分:1)

试试这个:

SELECT DISTINCT `subjects`.* 
FROM `subjects` 
INNER JOIN `classes_subjects` ON classes_subjects.subject_id = subjects.id 
INNER JOIN `classes_academic_years` ON classes_academic_years.id = classes_subjects.class_academic_year_id 
LEFT JOIN `professors_classes_subjects` ON professors_classes_subjects.class_academic_year_id = classes_subjects.class_academic_year_id and professors_classes_subjects.subject_id = classes_subjects.subject_id 
left join `class_masters` on class_masters.class_academic_year_id = classes_academic_years.id

left join professors_subjects on professors_subjects.subject_id = subjects.id

WHERE (((professors_classes_subjects.id is null or professors_classes_subjects.professor_id = 198) and class_masters.professor_id = 198 ) 
AND (classes_academic_years.academic_year_id = 3) 
AND (subjects.default = 0)) 

OR professors_subjects.professor_id = 198

ORDER BY `name` asc;

我引入了另一个左连接(用于连接第一个查询中的表),并将OR逻辑添加到整个WHERE子句中。