数据库概论sql——数据查询
1.单表查询
1.order by 子句
对查询结果进行一个或多个属性列的升序(ASC)或降序(DESC)排列 默认为升序
例:查询选修了3号课程的学生学号和成绩,查询结果按分数的降序排列
select Sno,Grade
from SC
where Cno='3'
order by Grade DESC;
2.group by 子句
将查询的结果按某一列或多列的值分组,值相等的为一组;
为了细化聚集函数的作用对象。分组后聚集函数将作用于每一个组,即每一个组都有一个函数值。
例:查询选修了一门以上课程的学生学号;
select Sno
from SC group by Sno
having COUNT(Cno)>1
where子句中是不能用聚集函数作为条件表达式的
例如where avg(Grade)>90就是错误的
2.连接查询
1.自然连接
例:查询选修2号课程且成绩在90分以上的所有学生的学号和姓名
select Student.Sno,Sname
from Student,SC
where Student.Sno=SC.Sno and SC.Cno='2' and SC.Grade>90;
用‘=’表示将两表连接
2.自身连接
3.外连接
有时想把Student表作为主体列出每个学生的基本情况及其选课情况
select Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
from Student left outer join SC on (Student.Sno=SC.Sno)
类似表的拼接吧
注意:SQL 中等于 后面这能是某一个特定值,而IN 可以是一个结果集。如果结果集只有一个值时“=”等价于“IN” ,如果结果集有多个值时,IN 等价于 多个 “=”或。
4.多表连接
就是多个表的连接
3.嵌套查询
外层为父查询,内层为子查询
1.不相关子查询
子查询可独立执行,不依赖于父查询表的查询,称为不相关子查询。 执行过程: (1)先执行子查询,其结果不会被显示,而是返回给外部查询来作为外部查询的查询条件; (2)根据子查询的结果,执行外部查询。
例:查询年龄小于所有学生平均年龄的学生
SELECT *
FROM student
WHERE 年龄 < ( SELECT AVG(年龄)
FROM student
本例中只用到了一个表student,先执行子查询,计算出所有学生的平均年龄,再将该平均年龄作为外部查询的查询条件,进而查询出比所有学生平均年龄小的学生的信息。
2.相关子查询
相关子查询 构造子查询的查询条件时需要用到父查询的某一个属性列,这样的查询称为相关子查询。
相关子查询是无法独立执行的,因为它必然含有对外部查询表中元组分量的引用。 其执行过程为: (1)按顺序从外部查询中取出一个元组,将元组的相关分量值传递给子查询; (2)执行子查询,得到结果值; (3)外部查询根据子查询返回的结果或结果集确定取出的这一行元组是否满足条件;若外层的where子句返回真值,说明符合;否则不符合,舍弃。 (4)重复步骤1-3,直到外部查询表中的所有元组都被处理完毕。
最常见的相关子查询是EXISTS引导的子查询。 EXISTS 引导的子查询不返回数据,而是返回是否存在满足子查询的外层查询元组的判断(真/假),主查询根据该判断来逐条取舍元组。
例:查询至少有一门课不及格的学生姓名
SELECT 姓名 FROM student
WHERE EXISTS
( SELECT * FROM course
WHERE course.学号 = student.学号
AND 成绩 < 60
)
本例中,执行子查询时,先从外部查询中取出一个元组,也就是从student表中取出一个元组(学生信息),并得到该学生学号作为子查询的查询条件。若该学生存在有至少一门课程不及格,则该学生满足条件,exists返回为真,外层查询保留该元组;否则舍弃。 本例同样可以使用连接查询来实现,而且貌似使用连接查询来实现会更简单;接下来再看一个例子,就能体会到相关子查询的方便之处。
查询所有课程都及格了的学生:
SELECT 姓名 FROM student
WHERE NOT EXISTS
(SELECT * FROM course
WHERE course.学号 = student.学号
AND course.成绩 < 60)
查询所有课程都及格了的学生,其实就是该学生不存在有不及格的课程。 此例若用连接查询来实现,必然相当繁琐,显然用相关子查询是最简便的。
4.集合查询
包括并操作(union),交操作(intersect),差操作(except)
挺简单的不写了
5.基于派生表的查询
子查询不仅可以出现在where子句中,还可以出现在from子句中,这时子查询生成的临时派生表成为主查询的查询对象。
例:找出每个学生超过他自己选修课程平均成绩的课程号
select Sno,Cno
from SC,(select Sno ,Avg(Grade) from SC group by Sno)
AS Avg_sc(avg_sno,avg_grade)
where SC.Sno=Avg_sc.avg_sno and SC.Grade>=Avg_sc.avg_grade;
这里的from子句中的子查询生成一个派生表Avg_sc。该表有avg_sno和avg_cno这两个属性组成。