SQL功能极强,由于其巧妙的设计,完成核心功能只需要9个动词。
SQL功能 | 动词 |
数据查询 | select |
数据定义 | create(创建,)drop(删除),alter(改变) |
数据操纵 | insert(插入 )update(更新) delete(删除) |
数据控制 | grant(授权)revoke(取消授权) |
关系数据库系统支持三级模式结构,其模式、外模式和内模式中的基本对象有模式,表,视图和索引等,因此SQL的数据定义功能包括模式定义、表定义、视图和索引定义.SQL数据定义语句如下表:
操作对象/操作方式 | 创建 | 删除 | 修改 |
模式 | create schema | drop schema | |
表 | create table | drop table | alter table |
视图 | create view | drop view | |
索引 | create index | drop index | alter index |
我们定义三个表 学生表:Student(Sno,Sname,Ssex,Sage,Sdept) 课程表:Course(Cno,Cname,Cpno,Ccredit)
学生选课表:SC(Sno,Cno,Grade)
学生表:Student
CREATE TABLE Student (Sno CHAR(9) PRIMARY KEY,/*列级完整性约束条件,Sno是主码*/ Sname CHAR(20)UNIQUE, /*Sname 取唯一的值*/ Ssex CHAR(20), Sage SMALLINT, Sdept CHAR(20) );
课程表:Course
CREATE TABLE Course (Cno CHAR(4) PRIMARY KEY, Cname CHAR(40) NOT NULL, Cpno CHAR(4), Ccredit SMALLINT, FOREIGN KEY(Cpno) REFERENCES Course(Cno) /*表级完整性约束条件,Cpno是外码,被参照表是Course,被参照表是Cno*/ );
选课表SC
CREATE TABLE SC (Sno CHAR(9), Cno CHAR(4), Grade SMALLINT, PRIMARY KEY(Sno,Cno), FOREIGN KEY(Sno)REFERENCES Student(Sno), FOREIGN KEY(Cno)REFERENCES Course(Cno) );
然后会建立三个表 :如下
接下来插入数据:
insert into Student(Sno,Sname,Ssex,Sage,Sdept) values('201215121','李勇','男',20,'CS');
按上述方式插入所有的数据:如下:
数据的查询:
查询条件 | 谓词 |
比较 | =,>,<,<=,!=,!>,<>,NOT+上述比较运算符 |
确定范围 | beetween and ,not between (上限)and(下线) |
确定集合 | IN, NOT IN |
字符匹配 | like,not like |
空值 | IS NULL,IS NOT NULL |
多重条件(逻辑运算) | AND,OR,NOT |
列如:查询既不是计算机,数学系,也不是信息系的学生的姓名和性别。
select Sname,Ssex from Student where Sdept NOT IN('CS','MA','IS');
order by子句对查询结果按照一个或者多个属性列升序(ASC)降序(DESC)排列,默认为升序。
查询全体学生,查询结果在同一系号升序,同一系按年龄降序。
select * from student order by Sdept,Sage DESC;
聚集函数
COUNT(*) | 统计元组个数 |
COUNT([DISTINCT|ALL]<列明>) | 统计一列中值的个数 |
SUM([DISTINCT|ALL]<列明>) | 计算一列中的和(必须为数值型) |
AVG([DISTINCT|ALL]<列明>) | 计算平均值(数值型) |
MAX([DISTINCT|ALL]<列明>) | 最大 |
MIN([DISTINCT|ALL]<列明>) | 最小 |
GROUP BY(group by)将查询结果分组。分组后的聚集函数(只能用于select子句或者group by中的having)作用于每个组,每组由一个函数值。
查询成绩大于90分的学号和平均成绩:
select Sno,AVG(Grade) from SC group by Sno having AVG(Grade)>=90;
连接查询:
查询每门课的间接先修课。要对Course表取两个别名。
select FIRST.Cno,SECOND.Cpno from Course FIRST,Course SECOND where First.Cpno=SECOND.Cno;
嵌套查询:
列如:
select Sname from Student where Sno IN (select Sno from SC where Cno='2');
子查询select中不能使用order by子句,order by只对最终结果排序。
如果子查询的查询条件依赖于父查询,这类查询称为相关子查询。
找出每个学生中比他选修课平均成绩高的课程号:
select Sno from SC x where Grade>=(select AVG(Grade) from SC y where y.Sno=x.Sno );
从外层查询中取出一个元组x,将元组x的Sno值传送给内层查询,执行内层查询得到成绩的平均值,用该值代替内层查询得到外层查询。
列题:查询非计算机科学系中比计算机科学系中任意一个学生小的学生姓名和Sage。
select Sname,Sage from student where Sage<any(select Sage from Student where Sdept='CS') AND Sdept!='CS';
any | 大于查询结果中的某个值 >= <= != 等都可以。 |
all | 大于查询结果中的所有值 >= <= != 等都可以。 |
本查询也可以用聚焦函数实现。首先用子查询查出CS中最大年龄(20),然后在父类查询中查询非CS系小于20的学生。
select Sname,Sage from Student where Sage< (select MAX(Sage) from Student where Sdeot='CS') AND Sdept!='CS';
带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值true或者假false。
列如:选修了一号课程的学生姓名。
select Sname from Student where EXISTS (select * from SC where Sno=Student.Sno AND Cno='1');
集合运算:
并操作UNION 交操作INTERSECT 差操作EXCEPT
列如查询计算机科学系的学生及年龄不大于19岁的学生。
select * from Student where Sdept='CS' UNION select * from Student where Sage<10;
查询计算机科学系的学生与年龄不大于19岁学生的交集。(也就是查询计算机科学系中年龄不大于19岁的学生。)
select * from Student where Sdept='CS' INTERSERT select* FROM Student where Sage<=19;
参考书籍:数据库系统概论