mysql_leftjoin.txt
sampdb.zip
我们有一个记录学生的student表,有一个记录已发生考试或测验事件的grade_event表,还有一个记录每位学生的每次考试成绩的score表。现在查找缺考的学生。
# create student table for grade-keeping projectDROP TABLE IF EXISTS student;#@ _CREATE_TABLE_CREATE TABLE student(name VARCHAR(20) NOT NULL,sex ENUM('F','M') NOT NULL,student_id INT UNSIGNED NOT NULL AUTO_INCREMENT,PRIMARY KEY (student_id)) ENGINE=InnoDB;#@ _CREATE_TABLE_# create grade event table for grade-keeping projectDROP TABLE IF EXISTS grade_event;#@ _CREATE_TABLE_CREATE TABLE grade_event(date DATE NOT NULL,category ENUM('T','Q') NOT NULL,event_id INT UNSIGNED NOT NULL AUTO_INCREMENT,PRIMARY KEY (event_id)) ENGINE=InnoDB;#@ _CREATE_TABLE_# create score table for grade-keeping project# The PRIMARY KEY comprises two columns to prevent any combination# of event_id/student_id from appearing more than once.DROP TABLE IF EXISTS score;#@ _CREATE_TABLE_CREATE TABLE score(student_id INT UNSIGNED NOT NULL,event_id INT UNSIGNED NOT NULL,score INT NOT NULL,PRIMARY KEY (event_id, student_id),INDEX (student_id),FOREIGN KEY (event_id) REFERENCES grade_event (event_id),FOREIGN KEY (student_id) REFERENCES student (student_id)) ENGINE=InnoDB;#@ _CREATE_TABLE_##insert 语句见附件
要解决的问题是:确定哪些学生在某次考试或测验当天缺考了。也就是说 我们要查找学生和事件的组合没有在score表里出现过。
第一步:确定“学生+事件”的组合
from student inner join grade_event
第二步:“学生+事件”组合结果集,与score表一起执行left join操作
from student inner join grade_event
LEFT JOIN score
ON student.student_id=score.student_id
AND grade_event.event_id =score.event_id
第三步:将缺失的列筛选出来
where score.score is null
最终SQL为:
SELECT
student.name,
student.student_id,
grade_event.date,
grade_event.event_id,
grade_event.category
FROM
student
INNER JOIN
grade_event
LEFT JOIN
score
ON
student.student_id=score.student_id
AND grade_event.event_id =score.event_id
WHERE
score.score IS NULL
ORDER BY
student.student_id,
grade_event.event_id;
