第三节 数据查询
(一)格式
select [all|distinct] <目标列表达式>[,<目标列表达式>]...
from <表名或视图名>[,<表名或视图名>]...
[where<条件表达式>]
[group by<列名1>[having <条件表达式>]]
[order by<列名2>[asc|desc]]
1.目标列表达式*/表名.*/count(*)/字段名表达式
2.条件表达式
(二)分类介绍查询命令
单表查询、连接查询、嵌套查询、集合查询
一、单表查询
1.选择表中的若干列
1 select Sno,Sname from Student;
2 select * from Student;
3 select Sname,200-Sage from Student;
2.选择表中的若干元组
1 select Sname from Student where Sdept='cs';
2 select Sname from S where Sage beteween 20 and 30;
3 select Sname from S where Sage IN('CS','MA','IS');
4 select * from S where Sno like '200215121';
5 select * from S where Sno='200215121';如果like后边不跟通配符,like可以等于=
6 select Sname from S where Sname like '刘%'; 刘贝 刘小明
7 select Sname from S where Sanme like '刘_'; 刘贝 刘明
8 select * from Course where Cname like 'DB\_%I__'escape'\';查询以DB_开头,且倒数第3个字符是i的课程
9 select Sno from SC where Grade IS NULL; IS不能写成=
10 AND高于OR
3.对查询结果排序
select Sno from SC where Cno='3'order by Grade desc;
4.使用库函数
selsect avg(*)from SC;
5.对查询结果进行分组
select ClassID from Student group by ClassID having count(*) >50;//表中是学生StuID,学生姓名Stu,学生所在班级ClasID。问学生数大于50的班级,途牛一面
select Sno from SC group by Sno having count(*)>3;//表中是学号Sno,课程号Cno,成绩Grade,问查询选修了3门以上课程的学生学号
二、连接查询
1.格式:
1 [<表名1>.]<列名1><比较运算符>[<表名2>,]<列名2>
2 [<表名1>.]<列名1>between[<表名2>.]<列名2>and[<表名3>.]<列名3>
1.等值与非等值连接
查询每个学生及其选修课程的情况
selece Student.*,SC.* from Sthdent,SC where Student.Sno=SC.Sno;
2.自身连接
Course(Cno课程号, Cname课程名称, Cpno先行课, Ccredit学分)
因为Course表中只有直接先行课,没有间接先行课,所以需要为Corse取两个别名,分别是first和second,即first(Cno, Cname, Cpno, Ccredit) second(Cno, Cname, Cpno, Ccredit)
查询每一门课程的间接选修课
select first.Cno ,second.Cpno from Course first,Course second where first.Cpno=second.Cno;
3.外连接:左外连接、右外连接
外连接:在通常的连接(内连接)中,只能满足连接条件的元组才能作为结果输出。比如Student中有200215123和200215125两个学生没有选课,在SC表中,就没有相应的选课记录,
所以当需要列出所有学生的选课信息时,就会舍弃200215123和200215125两个学生(左连接)。
若是某个学生并没有选课,扔想把舍弃的Student元组保存在结果关系中,并在SC表的属性上填写null,这时就需要用外连接。
左外连接列出做边关系的所有元组,右外连接列出右边关系的所有元组
列出所有学生的选课信息,包括没有选课的学生
select Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade FROM Student LEFT OUT JOIN SC ON(Student.Sno=SC.Sno);
4.复合条件连接
where中有多个连接条件
查询2号课程且成绩在90分以上的所有学生
select Student.* from Student,SC where Student.Sno=SC.Sno and SC.Cno='2' and SC.Grade>90;
三、嵌套查询
将一个查询嵌套在另一个查询快的where语句或者是having短语的条件中的查询成为嵌套查询
1.带IN的查询
查询与“刘晨”在同一个系学习的学生
select Sno,Sname,Sdept from Student where Sdept IN(select Sdept from Student where Sname="刘晨");
当然,本题同样可以用自身查询来做:
select S1.Sno,S1.Sname,S1.Sdept from Student S1, Student S2 where S1.Sdept=S2.Sdept and S2.Sname="刘晨":
2.带比较运算符的子查询
同样,假设一个学生只能在一个系里面学习,所以上边的in可以用=来代替
select Sno,Sname,Sdept from Student where Sdept=(select Sdept from Student where Sname="刘晨");
3.带any some all等谓语的子查询
查询其他系中比计算机科学系某一学生年龄小的学生姓名和年龄
select Sname,Sage from Student where Sage<any (select Sage from Student where Sdept='CS') and Sdept <>'CS';
查询其他系中比计算机科学系所有学生年龄都小的学生姓名和年龄
select Sname,Sage from Student where Sage<all(select Sage from Student where Sdept='CS') and Sdept<>'CS';
4.带有exists谓语的子查询
exists代表存在量词,带有exists不返回任何数据,而是返回flase或true
查询所有选修了1号课程的学生姓名
select Sname from Student where Sno=(select Sno from SC where Cno='1'));
select Sname from Student where exsts (select *from SC where Sno=Student.Sno and Cno='1');
四、集合查询
集合查询主要包括了并运算union、交运算intersect、差运算except。注意!参加集合运算的各查询结果的列数必须是相同的,对应项的数据类型也必须是相同的
查询选修了1号课程或2号课程的学生姓名
select Sname from Student where Sno=(select Sno from SC where Cno='1'or Cno='2');
select Sname from Student where Sno=(select Sno from SC where Cno in ('1','2'));
select Sname from Student where Sno=(select Sno from SC where Cno='1' union select Sno from SC where Cno='2' );