常用的多表连接查询
内连接(INNER JOIN)
外连接
左外连接 (LEFT JOIN)
右外连接 (RIGHT JOIN)
内连接
//内连接是查询有相同记录的
内连接使用比较运算符根据每个表的通用列中的值匹配两个表中的行
查询结果
内连接语句
语法:
示例:
三表内连接
示例:
SELECT S.studentName AS 姓名,SU.subjectName AS 课程,R.studentResult AS 成绩
FROM student AS S
INNER JOIN `result` AS R ON (S.`studentNo` = R.`studentNo`)
INNER JOIN `subject` AS SU ON (SU.subjectNo=R.subjectNo);
左外连接
//无匹配返回NULL
示例:
SELECT S.studentName,R.subjectNo,R.studentResult
FROM student AS S
LEFT JOIN result AS R
ON S.studentNo = R.studentNo;
问题:猜一猜:这样写,返回的查询结果是一样的吗?
SELECT S.studentName,R.subjectNo,R.studentResult
FROM result AS R
LEFT JOIN student AS S
ON S.studentNo = R.studentNo;
//不一样,主表和从表位置已互换
右外连接
右外连接的原理与左外连接相同
右表逐条去匹配记录;否则NULL填充
示例:
SELECT 图书编号,图书名称,出版社名称
FROM 图书表
RIGHT JOIN 出版社表
ON 图书表.出版社编号 = 出版社表.出版社编号;
三种连接的对比
等值连接和内连接一样!
非等值连接
左边行数乘于右边行数
什么是子查询
语法:
SELECT … FROM 表1 WHERE 字段1 比较运算符(子查询)
注意:
将子查询和比较运算符联合使用,必须保证子查询返回的值不能多于一个
IN子查询
查询“Logic Java”课程考试成绩为60分的学生名单
问题;
查询参加“Logic Java”课程最近一次考试的在读学生名单
分析:
实现步骤
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java';
SELECT MAX(`examDate`) FROM `result` WHERE `subjectNo`= (
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java' );
参考语句
NOT IN子查询
问题
查询未参加“Logic Java”课程最近一次考试的在读学生名单
分析:
实现步骤
SELECT `studentNo`, `studentName` FROM `student` WHERE `studentNo`
NOT IN(
SELECT `studentNo` FROM `result`
WHERE `subjectNo` = (
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java'
) AND `examDate` = (
SELECT MAX(`examDate`) FROM `result` WHERE `subjectNo` = (
SELECT `subjectNo` FROM `subject`
WHERE `subjectName`='Logic Java')
)
)……
EXISTS子查询
问题:
如何用SQL语句检测temp表是否已经创建?
DROP TABLE IF EXISTS temp;
CREATE TABLE temp (
… … #省略建表语句
) ;
EXISTS关键字是否还有其他用法?
语法:
EXISTS子查询的语法;
SELECT …… FROM 表名 WHERE EXISTS(子查询);
子查询有返回结果: EXISTS子查询结果为TRUE
子查询无返回结果: EXISTS子查询结果为FALSE,
外层查询不执行
参考语句:
SELECT AVG(studentresult)+5 AS 平均分 FROM result
WHERE NOT EXISTS (
SELECT * FROM `result` WHERE `subjectNo` = (
SELECT `subjectNo` FROM `subject` WHERE `subjectName` = 'Logic Java'
) AND `examDate` = (
SELECT MAX(`examDate`) FROM `result` WHERE `subjectNo` = (
SELECT `subjectNo` FROM `subject`
WHERE `subjectName` = 'Logic Java')
) AND `studentResult` > 60)
AND `subjectNo` = ( SELECT `subjectNo` FROM `subject`
WHERE `subjectName` = 'Logic Java')
AND `examDate` = (
SELECT MAX(`examDate`) FROM `result` WHERE `subjectNo` = (
SELECT `subjectNo` FROM `subject`
WHERE `subjectName` = 'Logic Java') );
子查询注意事项
//WHERE子句 GROUP BY 子句 HAVING 子句 是可选子句,根据雨雾需求决定
示例:学员操作——制作学生成绩单
指导
训练要点
任何允许使用表达式的地方都可以使用子查询
需求说明
为每个学生制作在校期间每门课程的成绩单,要求每个学生参加每门课程的最后一次考试成绩作为该生本课程的最终成绩
成绩单的数据项
学生姓名
课程所属的年级名称
课程名称
考试日期
考试成绩
分组查询用法
语法:
掌握GROUP BY子句实现分组查询
SELECT …… FROM <表名>
WHERE ……
GROUP BY ……
分组查询解析
问题:查询每门课程的平均分,并且按照分数由高到低的顺序排列显示
SELECT `subjectNo`,AVG(`studentResult`) AS 课程平均成绩
FROM `result`
GROUP BY `subjectNo`
ORDER BY AVG(`studentResult`);
多列分组
分别统计每个年级男、女生人数
SELECT `gradeId` AS 年级编号,`sex` AS 性别,COUNT(*) AS 人数
FROM `student`
GROUP BY `gradeId`,`sex`
ORDER BY `gradeId`;
如何获得课程平均分及格的课程编号?
分组筛选
分组筛选语句
语法:
SELECT …… FROM <表名>
WHERE ……
GROUP BY ……
HAVING……
示例:
SELECT `subjectNo`,AVG(`studentResult`) AS 课程平均成绩
FROM `result`
GROUP BY `subjectNo`
HAVING AVG(`studentResult`) >=60;
WHERE与HAVING对比
用来筛选 FROM 子句中指定的操作所产生的行
用来分组 WHERE 子句的输出
用来从分组的结果中筛选行
问题:如何同时从这两个表中取得数据?
常用的多表连接查询
内连接(INNER JOIN)
外连接
总结