一、简单查询
二、汇总分析
三、复杂查询
topN问题N=1分组取每组最大(小)值
题目:按课程号分组取成绩最大(小)值所在行的数据方法一:自join
方法二:关联子查询
- 每组最大的N条记录(N大于等于2)
题目:查询各科成绩前两名的记录
方法一:关联子查询
方法二:自联结
方法三、union all
值得注意的是第三种方法看起来似乎并不准确,因为它忽略了成绩并列的情况。四、多表查询
join
练习 还是章节前那四个表
查询所有学生的学号、姓名、选课数、总成绩
查询平均成绩大于85的所有学生的学号、姓名和平均成绩
查询学生的选课情况:学号,姓名,课程号,课程名称
最后发现把没有选课的学号为0004的同学漏了,为了避免这种情况,应该score表先与course表 join 得到一个表,student在与其left join
查询出每门课程的及格人数和不及格人数
也可以稍微修改一下,利用count对null求和为0,得出另一种方法
使用分段[100-85],[85-70],[70-60],[‹60]来统计各科成绩,分别统计:各分数段人数,课程号和课程名称
查询课程编号为0003且课程成绩在80分以上的学生的学号和姓名
SQL行列互换
第1步,
select 学号,'课程号0001','课程号0002','课程号0003'
from score
group by 学号
第2步,使用case表达式,替换常量列为对应的成绩
如果直接运行整个SQL语句只会输出前3行,因为select……group by……默认输出每个分类的第一行数据。因此这里需要添加聚合函数max或者sum。
最后还有一点问题没有解决:原表中学号为0001的学生的0002课程成绩是不知道,并不是0,而按照上图结果却是为0
还需要进行修改
当聚合函数与null作运算时有:
count(*)时:将null那一行算入。
count(某列):不会统计null那一行。
sum: null不会对sum产生影响
avg:null对其产生影响
max 或者min:null不会对其产生影响因此当且仅当某个学号对应的某个课程号每一行都为null,sum或者max才为null,也就是说某个学生根本没有选择那一门课程,成绩就为null。符号我们的要求。
五、如何提高SQL查询效率
1. select子句中尽量避免使用*,不要返回用不到的任何字段
2. where子句比较符号左侧避免函数这会导致数据库引擎进行全表扫描,从而增加运行时间。where子句中遇到函数或加减乘除的运算,应当将其移到右侧。3. 尽量避免使用in和not inin和not in也会导致数据库进行全表搜索,从而增加运行时间,对于连续的数值,能用 between 就不要用 in 。
4. 尽量避免使用or
or会导致数据库进行全表搜索,有时可以用union连接,避免使用or5.使用limit子句限制返回的数据行数