持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天
子查询和连接查询
-- 查询年龄最大的学生的姓名(子查询/嵌套的查询)
select stuname from tb_student where stubirth=(
select min(stubirth) from tb_student
);
-- 查询两门以上的课程的学生姓名(子查询/分组条件/集合运算)
select stuname from tb_student where stuid in (
select stuid from tb_score group by stuid having count(stuid)>2
);
-- 查询学生姓名,课程名称及考试成绩(连接查询)
select stuname,couname,scmark from tb_student t1,tb_course t2,tb_score t3 where t1.stuid=t3.stuid and t2.couid=t3.couid;
-- 查询选课学生的姓名和平均成绩
-- 第一种
select stuname,avgmark from tb_student t1,(select stuid,avg(scmark) as avgmark from tb_score group by stuid) t2 where t1.stuid=t2.stuid;
-- 第二种(内连接)
select stuname,avgmark from tb_student t1 inner join (select stuid,avg(scmark) as avgmark from tb_score group by stuid) t2 on t1.stuid=t2.stuid;
-- 查询每个学生的姓名和选课数量(左外连接和子查询)
-- 内连接查询
select stuname,total from tb_student t1 inner join (select stuid,count(stuid) as total from tb_score group by stuid) t2 on t1.stuid=t2.stuid;
-- 这里注意使用内连接只能把选了课的人查询出来,那些没有选课的查不出来,所以这里得用左连接
select stuname,total from tb_student t1 left outer join (select stuid,count(stuid) as total from tb_score group by stuid) t2 on t1.stuid=t2.stuid;
-- 这里的左连接其实就是把左表(前面的表)查完整
连接查询分为两大类:内连接和外连接
- 内连接:(inner join)
表1 inner join 表2 on 连接条件 - 外连接
外连接分为三类:左外连接,右外连接(全外连接mysql不支持)
- 左外连接(left outer join):左外连接就是把左表信息查全
表1 left outer join 表2 on 连接条件 - 右外连接(right outer join):右外连接就是把右表信息查全
表1 right outer join 表2 on 连接条件 - 全外连接
表1 full outer join 表2 on 连接条件 - 注意以上的outer都可以省略
分页查询
因为mysql最大单表支持65535TB
单列最大支持4G -- LONGBLOB类型/LONGTEXT类型
因此我没会采用分页查看
-- 查询选课学生的姓名和平均成绩
select stuname,avgmark from tb_student t1,(select stuid,avg(scmark) as avgmark from tb_score group by stuid) t2 where t1.stuid=t2.stuid order by scmark desc limit 5 offset 5;
- limit 5:每次最多显示5条数据
- offset 5:偏移5条(跳过5条)
- limit 5,5:跳过5条看5条
书写SQL语句的注意事项
- 给数据库和表命名的时候注意区分大小写
- 作为筛选条件的字符串区分大小写看设置的校对规则
- 数据库中的对象通常会加以前缀区分(table/view/index/function/procedure/trigger)
- 在查询时,通常不推荐使用in或者not in集合运算和distinct去重操作,可以考虑用exists或者not exists替代掉集合运算和去重操作(去重和集合运算的效率在大表里面太低了)