持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第22天,点击查看活动详情 1.EXISTS子查询
语法:
子查询有返回结果: EXISTS子查询结果为TRUE,则执行外层查询
子查询无返回结果: EXISTS子查询结果为FALSE,外层查询不执行
当数据量大的时候使用exists,如数据量于一万以上使用,数据量少时可以使用in
示例:
/*1.检查‘logic java’ 课程最近一次考试成绩*/
/*2.如果有80分以上,显示分数排前5名的学员学号和分数*/
select * from result;
select studentNo as 学生学号, studentResult as 学生成绩 from result where exists (
select studentNo,studentResult from result where examDate in (
select max(r.examDate)
from result as r inner join subject as s on r.subjectNo = s.subjectNo where subjectName = 'logic java' )
)and studentResult>80
order by studentResult
desc limit 5;
2.not exists 子查询
可以采用NOT EXISTS检测是否全部未通过考试,即不存在“成绩>=60分”的记录
3.子查询注意事项
(1)任何允许使用表达式的地方都可以使用子查询
(2)嵌套在父查询SELECT语句的子查询可包括:
SELECT子句
FROM子句
WHERE子句
GROUP BY子句
HAVING子句
3)只出现在IN子查询中而没有出现在父查询中的列不能包含在输出列中
4.分组查询用法
SELECT列表中只能包含:
1.被分组的列
2.为每个分组返回一个值的表达式,如聚合函数
掌握GROUP BY子句实现分组查询语法:
SELECT ……
FROM <表名>
WHERE …… GROUP BY ……
示例:
SELECT `subjectNo`,AVG(`studentResult`)
AS 课程平均成绩 FROM `result`
GROUP BY `subjectNo`;
/*制作学生成绩单*/
select s.studentName as 学生姓名,
(select gradeName from grade where id =
su.gradeID) as 课程所属年级,
su.subjectName as 课程名称,
r1.examDate as 考试日期,
r1.studentResult as
成绩 from result as
r1 inner join student as
s on r1.studentNo = s.studentNo inner join subject as su on su.subjectNo = r1.subjectNo where r1.examDate in (
select max(examDate)
from result as r2 where r1.subjectNo
= r2.subjectNo group by r2.subjectNo )
order by su.gradeID;
/*分组查询没门课平均分*/
select subjectNo as 科目编号,
avg(studentResult) as
平均分 from result group by
subjectNo ORDER BY AVG(studentResult) desc;
/*分别统计每个年级男、女生人数*/
select gradeId as 年级编号,
sex as 性别,count(1) as 人数
from student group by gradeId,
sex order by gradeId;
5.分组筛选语句
语法:
SELECT ……
FROM <表名>
WHERE ……
GROUP BY ……
HAVING……
示例:
/*分组筛选出课程平均分大于等于60分的课程*/
select subjectNo as 课程编号,
avg(studentResult) as 平均分
from result
group by subjectNo
having 平均分>=60;
6.WHERE与HAVING对比
(1)WHERE子句
用来筛选 FROM 子句中指定的操作所产生的行
(2)GROUP BY子句
用来分组 WHERE 子句的输出
(3)HAVING子句
用来从分组的结果中筛选行
7.count(*)和count (1) 的区别
count(*)统计表里的所有数据条数,效率较低,
count(1)也是统计表里的所有数据,但效率比count(*) 高
8.常用的多表连接查询
(1)内连接(INNER JOIN)
内连接语句
SELECT …… SELECT ……
FROM 表1 等价于
FROM 表1,表2
INNER JOIN 表2
WHERE …… ON ……
示例:
SELECT `student`.`studentName`,`result`.`subjectNo`,
`result`.`studentResult` FROM `student`,
`result` WHERE `student`.`studentNo` = `result`.`studentNo`;
SELECT S.`studentName`,
R.`subjectNo`,
R.`studentResult`
FROM `student` AS S
INNER JOIN `result`
AS R ON (S.`studentNo` = R.`studentNo`);
三表内连接
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);
(2)外连接
左外连接 (LEFT JOIN)
主表(左表)student中数据逐条匹配表result中的数据
1.匹配,返回到结果集
2.无匹配,NULL值返回到结果集
示例:
/*左外连接 left join 前面的表为主表,以主表里的字段为依据,把从表里的数据填充给主表,从表里面没有的字段以null填充 left join 后面的表为从表*/
select s.studentName as 学生姓名,
r.subjectNo as 科目编号,
r.studentResult as 学生成绩
from student as s
left join result as r
on s.studentNo = r.studentNo;
右外连接 (RIGHT JOIN
右外连接的原理与左外连接相同
右表逐条去匹配记录;否则NULL填充
示例:
/*右外连接 right join前面的表为主表,以主表里的字段为依据,把从表里的数据填充给主表,从表里面没有的字段以null填充 right join 后面的表为从表 */
select r.subjectNo as 科目编号,
r.studentResult as 学生成绩,
s.studentNo as 学生编号
from result as r
right join student as s
on r.studentNo = s.studentNo;
9.使用临时表保存查询结果
create temporary table表名(查询语句)
提示:
临时表只在当前连接可见,连接关闭自动删除,修改临时表数据不影响原表数据
10.MySQL 如何把varchar类型转换为int类型,再做加法运算
cast(字段1 as int) + cast(字段2 as int)
示例
select trunk_breakers_num,branch_breakers_num,
(cast(trunk_breakers_num as int) + cast(branch_breakers_num as int))
as trunk_branch_breakers_num from t_health_line_dt;