单表查询中的GROUP BY子句
求各课程相应选课人数
select Cno,COUNT(Sno)
from SC
GROUP BY Cno;
带有HAVING短语指定筛选条件的查询
select Sno
from SC
GROUP BY Sno
HAVING COUNT(*)>3;
此处是先用GROUP BY子句进行分组,再用聚焦函数COUNT对每一组计数,在此基础上使用HAVING短语进行筛选,因为插入的数据没有满足此条件的,所以结果显示没有。
查询平均成绩达到条件的学生学号与平均成绩
此处因为WHERE子句不能用聚焦函数作为条件表达式,所以报错。
正确的查询语句如下:
select Sno,AVG(Grade)
from SC
GROUP BY Sno
HAVING AVG(Grade)>=90;
因为插入的数据中无满足条件的,所以没有结果截图
WHERE子句与HAVING短语的区别在于作用对象不同,前者作用于基本表或视图选择其中满足条件的元组,后者作用于组,选择其中满足条件的组。
连接查询
等值连接
当连接运算符为=时,称为等值连接,使用其他运算符的称为非等值连接。
查询学生及其选修课程的信息,该查询涉及两个表,此处通过其公共属性Sno来实现
select Student.*,SC.*
from Student,SC
WHERE Student.Sno=SC.Sno;
在本例中,WHERE子句中的属性名都加上了前缀,这是为了避免混淆,如果属性名在参与连接的各表中是唯一的,则可以省略,但在SQL Server中显示结果时前缀不会被显示。
使用自然连接来实现上述例子(在等值连接中吧目标列中重复的属性列去掉则为自然连接):
select Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
from Student,SC
WHERE Student.Sno=SC.Sno;
WHERE子句是由连接谓词与选择谓词组成的复合条件的查询
一条SQL语句可以同时完成选择和连接查询:
select Student.Sno,Sname
from Student,SC
WHERE Student.Sno=SC.Sno AND
SC.Cno='2'AND SC.Grade>80;
该查询比较高效,它先从SC表中挑出符合条件的元组然后和Student表中满足连接条件的元组进行连接从而得出最终的结果关系。
自身连接
连接操作不仅可以在两个表中进行,也可以一个表与自己进行连接,这就是自身连接。
查询每门课的间接选修课(即先修课的先修课),为此,我们要为该表去两个别名(可辨认即可)
select first.Cno,second.Cpno
from Course first,Course second
WHERE first.Cpno=second.Cno;
外连接
当想查询的信息中有某项信息为空时,如想要查询每个学生的基本情况及其选课情况,存在某些学生没选课的情况但仍要显示该学生为空的信息时就可以使用外连接。
select Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
from Student LEFT OUTER JOIN SC ON(Student.Sno=SC.Sno);
/*也可以使用USING来去掉结果中的重复值:FROM Student LEFT OUTER JOIN SC USING(Sno);*/
多表连接
连接操作除了可以是两表连接,自身连接外,还可以是两个以上的表进行连接,该连接称为多表连接。
查询每个学生的学号、姓名、选修的课程名及成绩
select Student.Sno,Sname,Cname,Grade
from Student,SC,Course
WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno;
在多表连接中,通常先进行两个表的连接,再将结果与第三个表连接,如此类推下去可以实现多表的连接,本例就是先将Student表与SC表连接,再将结果与Course表连接得到结果。
本次连接查询实验结束
下面附上创建表以及插入数据的语句:
create table Student
(Sno char(9) primary key,
Sname char(20) unique,
Ssex char(2),
Sage smallint,
Sdept char(20)
);
create table Course
(Cno char(4) primary key,
Cname char(40) not null,
Cpno char(4),
Ccredit smallint,
foreign key(Cpno) references Course(Cno)
);
create table SC
(Sno char(9),
Cno char(4),
Grade smallint,
primary key(Sno,Cno),
);
insert into Student(Sno,Sname,Ssex,Sage,Sdept)
values('201215121','李勇','男','20','CS'),
('201215122','刘晨','女','20','CS'),
('201215123','','女','18','MA'),
('201215125','张立','男','19','IS');
insert into Course(Cno,Cname,Cpno,Ccredit)
values('1','数据库','5','4'),
('2','数学',NULL,'2'),
('3','信息系统','1','4'),
('4','操作系统','6','3'),
('5','数据结构','7','4'),
('6','数据处理',NULL,'2'),
('7','PASCAL语言','6','4');
insert into SC(Sno,Cno,Grade)
values('201215121','1','92'),
('201215121','2','85'),
('201215121','3','88'),
('201215122','2','90'),
('201215122','3','80');