案例:
(a)学生students表
Sno | Sname | Age | Sex | Splace |
---|---|---|---|---|
990027 | 胡伟 | 22 | 男 | 湖南 |
990625 | 张春明 | 24 | 男 | 河北 |
990668 | 王昱 | 22 | 女 | 四川 |
990674 | 丁晓春 | 24 | 男 | 黑龙江 |
990676 | 贺正生 | 23 | 男 | 湖南 |
990684 | 刘文革 | 24 | 女 | 辽宁 |
991091 | 程会军 | 23 | 男 | 山西 |
(b)课程courses表
Cno | Cname | Credit |
---|---|---|
C1 | 数据库 | 3 |
C2 | 数据结构 | 3 |
C3 | 操作系统 | 4 |
C4 | 软件工程 | 3 |
(c)教师teachers表
Tno | Tname | Age | PS |
---|---|---|---|
1420 | 周振华 | 38 | 副教授 |
1481 | 刘建平 | 30 | 讲师 |
1433 | 王志伟 | 28 | 讲师 |
(d)选课 enrolls
Sno | Cno | Grade |
---|---|---|
990027 | C1 | 90 |
990027 | C3 | 95 |
990027 | C4 | 88 |
990652 | C1 | 88 |
990652 | C4 | 83 |
990668 | C3 | 84 |
990674 | C2 | 77 |
990676 | C3 | 90 |
990684 | C3 | 85 |
990684 | C1 | 82 |
991091 | C2 | 93 |
(e)任课teaching
Cno | Class | Tno | Snum |
---|---|---|---|
C1 | E851 | 1420 | 30 |
C2 | E851 | 1420 | 22 |
C3 | E651 | 1481 | 30 |
C3 | E852 | 1481 | 28 |
C4 | E851 | 1433 | 24 |
C1 | E852 | 1420 | 28 |
表操作
例 1 对于表的教学管理数据库中的表 STUDENTS ,可以定义如下:
create table students(
Sno int,
Sname varchar(255),
Age int,
Sex varchar(255),
Splace varchar(255),
primary key(Sno)
)
例 2 对于表的教学管理数据库中的表 ENROLLS ,可以定义如下:
create table enrolls(
Sno int,
Cno varchar(5),
Grade int,
primary key(Sno,Cno),
foreign key(Sno) references students(Sno),
foreign key(Cno) references courses(Cno)
);
例 3 根据表的 STUDENTS 表,建立一个只包含学号、姓名、年龄的女学生表。
create table girl
as select Sno,Sname,Age from students
where sex='女'
例 4 删除教师表 TEACHER 。
drop table teacher
例 5 在教师表中增加住址列。
alter table teachers add (addr varchar(50))
例 6 把 STUDENTS 表中的 BPLACE 列删除,并且把引用 BPLACE 列的所有视图和约束也一起删除。
alter table students drop Splace cascade
例 7 补充定义 ENROLLS 表的主关键字。
alter table enrolls add primary key (Sno,Cno)
单表操作
找出 3 个学分的课程号和课程名。
select Cno,Cname from courses where Credit=3
查询年龄大于 22 岁的学生情况。
select * from students where Age>22
找出籍贯为河北的男生的姓名和年龄。
select Sname,Age from students where Splace='河北' and Sex='男'
找出年龄在 20 ~ 23 岁之间的学生的学号、姓名和年龄,并按年龄升序排序。 (ASC (升序)或 DESC (降序)声明排序的方式,缺省为升序。 )
select Sno,Sname,Age from students where Age between 20 and 23 order by Age
找出年龄小于 23 岁、籍贯是湖南或湖北的学生的姓名和性别。(条件比较运算符=、<和逻辑运算符 AND (与),此外还可以使用的运算符有:>(大于)、>=(大于等于)、<=(小于等于)、<>(不等于)、 NOT (非)、 OR (或)等。
谓词 LIKE 只能与字符串联用,常常是 “ <列名> LIKE pattern” 的格式。特殊字符 “_” 和 “%” 作为通配符。
谓词 IN 表示指定的属性应与后面的集合(括号中的值集或某个查询子句的结果)中的某个值相匹配,实际上是一系列的 OR (或)的缩写。谓词 NOT IN 表示指定的属性不与后面的集合中的某个值相匹配。
谓词 BETWEEN 是 “ 包含于 … 之中 ” 的意思。)
select Sname,Sex from students where Age<23 and (Splace='湖南' or Splace='湖北')
select Sname,Sex from students where Age<23 and Splace in ('湖南','湖北')
select Sname,Sex from students where Age<23 and Splace like '湖%'
找出学生表中籍贯是空值的学生的姓名和性别。(在 SQL 中不能使用条件:<列名>= NULL 。在 SQL 中只有一个特殊的查询条件允许查询 NULL 值:)
select Sname,Sex from students where Splace is null
多表操作
找出成绩为 95 分的学生的姓名。
select Sname from students,enrolls where Grade=95 and enrolls.Sno=students.Sno
select Sname from students where Sno in (select Sno from enrolls where Grade=95)
找出成绩在 90 分以上的学生的姓名
select Sname from students,enrolls where Grade>90 and enrolls.Sno=students.Sno
select Sname from students where Sno in (select Sno from enrolls where Grade>90)
select Sname from students where Sno = any (select Sno from enrolls where Grade>90)
查询全部学生的学生名和所学课程号及成绩。
select Sname,Cno,Grade from students,enrolls where students.Sno=enrolls.Sno
找出籍贯为山西或河北,成绩为 90 分以上的学生的姓名、籍贯和成绩。(当构造多表连接查询命令时,必须遵循两条规则。第一,连接条件数正好比表数少 1 (若有三个表,就有两个连接条件 ) ;第二,若一个表中的主关键字是由多个列组成,则对此主关键字中的每一个列都要有一个连接条件(也有少数例外情况))
select Sname,Splace,Grade from students,enrolls where (Splace ='山西' or Splace='河北') and Grade>90 and students.Sno=enrolls.Sno
查出课程成绩在 80 分以上的女学生的姓名、课程名和成绩。
select Sname,Cname,Grade from students,courses,enrolls where students.Sno=enrolls.Sno and courses.Cno=enrolls.Cno and Grade>80 and Sex='女'
表达式与函数的使用
查询各课程的学时数。(算术表达式由算术运算符+、-、 * 、/与列名或数值常量所组成。)
select Cname,Course_time=Credit*16 from courses
找出教师的最小年龄。(内部函数: SQL 标准中只使用 COUNT 、 SUM 、 AVG 、 MAX 、 MIN 函数,称之为聚集函数( Set Function )。 COUNT 函数的结果是该列统计值的总数目, SUM 函数求该列统计值之和, AVG 函数求该列统计值之平均值, MAX 函数求该列最大值, MIN 函数求该列最小值。)
select min(Age) from teachers
统计年龄小于等于 22 岁的学生人数
select count(*) from students where Age<=22
找出学生的平均成绩和所学课程门数。
select Sno,avg(Grade),count(Cno) from enrolls group by Sno
找出年龄超过平均年龄的学生姓名。
select Sname from students where Age(select avg(Age) from students)
找出各课程的平均成绩,按课程号分组,且只选择学生超过 3 人的课程的成绩。
GROUP BY 子句把一个表按某一指定列(或一些列)上的值相等的原则分组,然后再对每组数据进行规定的操作。
GROUP BY 子句总是跟在 WHERE 子句后面,当 WHERE 子句缺省时,它跟在 FROM 子句后面。
HAVING 子句常用于在计算出聚集之后对行的查询进行控制。)
select Cno,avg(Grade) students=count(*) from enrolls group by Cno having count(*)>3
查询没有选任何课程的学生的学号和姓名。(当一个子查询涉及到一个来自外部查询的列时,称为相关子查询( Correlated Subquery) 。相关子查询要用到存在测试谓词 EXISTS 和 NOT EXISTS ,以及 ALL 、 ANY ( SOME )等。)
select students.Sno,Sname from students where students.Sno not in (select enrolls.Sno from enrolls where enrolls.Sno=students.Sno )
查询哪些课程只有男生选读
select Cname from courses where Cno in ( select Cno from enrolls where Sno in (select Sno from students where Sex='男'))