有三张表:
学生表student(stu_id, stu_name)
成绩表scores(stu_id, subject, score)
补考成绩表(stu_id,subject,score)
其中:stu_id:ID,stu_name:姓名,subject:课程,score:成绩
输出:
姓名、课程和成绩 (没有补考,以成绩表为准,有补考,以成绩表和补考成绩表的较大者为准)
分析:
a. 成绩表和补考成绩表左联接,利用CASE WHEN来决定输出哪个成绩。
b. 然后和学生表左联接,获取对应的姓名
1. 准备表和数据
这里以MySQL数据库为例
-- 创建学生表CREATE TABLE `student` ( `stu_id` TINYINT NOT NULL, `stu_name` varchar(8) NOT NULL, PRIMARY KEY (`stu_id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;-- 创建成绩表CREATE TABLE `scores` ( `stu_id` TINYINT NOT NULL, `subject` varchar(16) NOT NULL, `score` TINYINT NOT NULL DEFAULT 0, PRIMARY KEY (`stu_id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;-- 创建补考成绩表CREATE TABLE `scores_sup` ( `stu_id` TINYINT NOT NULL, `subject` varchar(16) NOT NULL, `score` TINYINT NOT NULL DEFAULT 0, PRIMARY KEY (`stu_id`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;-- 插入测试数据INSERT INTO `student`( stu_id, stu_name)VALUES('1', '张三'),('2', '李四'),('3', '王五');INSERT INTO `scores`( stu_id, subject, score)VALUES('1', '语文', 60),('2', '数学', 65),('1', '英语', 70),('1', '数学', 56),('2', '语文', 49),('2', '英语', 58),('3', '语文', 57),('3', '数学', 54),('3', '英语', 79);INSERT INTO `scores_sup`( stu_id, subject, score)VALUES('1', '数学', 78),('2', '语文', 80),('2', '英语', 68),('3', '语文', 53),('3', '数学', 59);
2. 查询语句:
SELECT s.stu_name, a.subject, CASE WHEN a.score >= 60 -- 成绩通过,以成绩表为准 THEN a.score WHEN a.score < b.score -- 成绩没有补考的成绩高,以补考成绩为准 THEN b.score ELSE a.score -- 成绩比补考的成绩高,以成绩表为准 END AS scoreFROM scores aLEFT JOIN scores_sup bON a.stu_id = b.stu_idAND a.subject = b.subjectLEFT JOIN student sON a.stu_id = s.stu_id;
3. 输出:
+----------+---------+-------+
| stu_name | subject | score |
+----------+---------+-------+
| 张三 | 数学 | 78 |
| 李四 | 语文 | 80 |
| 李四 | 英语 | 68 |
| 王五 | 语文 | 57 |
| 王五 | 数学 | 59 |
| 张三 | 语文 | 60 |
| 李四 | 数学 | 65 |
| 张三 | 英语 | 70 |
| 王五 | 英语 | 79 |
+----------+---------+-------+