SQL 功能 |
动词 |
---|---|
数据查询 | SELECT |
数据定义 | CREATE , DROP , ALTER |
数据操纵 | INSERT , UPDATE , DELETE |
数据控制 | GRANT , REVOKE |
SQL
支持关系数据库三级模式结构
<作图>
学生表 | Student(Sno,Sname,Ssex,Sage,Sdept)
课程表 | Course(Cno,Cname,Cpno,Ccredit)
学生选课表 | SC(Sno,Cno,Grade)
操作对象 | 创建 | 删除 | 修改 |
---|---|---|---|
模式 | CREATE SCHEMA |
DROP SCHEMA |
|
表 | CREATE TABLE |
DROP TABLE |
ALTER TABLE |
视图 | CREATE VIEW |
DROP VIEW |
|
索引 | CREATE INDEX |
DROP INDEX |
定义模式
CREATE SCHEMA <模式名> AUTHORIZATION <用户名>;
create schema <模式名> authorization <用户名>;
如果没有指定 <模式名>,那么 <模式名> 隐含为 <用户名>
定义模式实际上定义了一个命名空间。在这个空间中可以定义该模式包含的数据库对象,例如基本表、视图、索引等。
删除模式
DROP SCHEMA <模式名> <CASCADE|RESTRICT>;
CASCADE
(级联)
RESTRICT
(限制)
定义基本表
CREATE TABLE <表名>
(
<列名> <数据类型> <列级完整性约束条件>,
<列名> <数据类型> <列级完整性约束条件>,
<列名> <数据类型> <列级完整性约束条件>
<表级完整性约束条件>
);
建立学生表Student
,学号是主码,姓名取值唯一。
CREATE TABLE Student ( Sno CHAR(9) PRIMARY KEY, /* 列级完整性约束条件*/ Sname CHAR(20) UNIQUE, /* Sname取唯一值*/ Ssex CHAR(2), Sage SMALLINT, Sdept CHAR(20) );
建立一个“学生选课”表SC
CREATE TABLE SC ( Sno CHAR(9), Cno CHAR(4), Grade SMALLINT, PRIMARY KEY (Sno, Cno), /* 作为表级完整性进行定义*/ FOREIGN KEY (Sno) REFERENCES Student(Sno), /* 表级完整性约束条件,Sno是外码,被参照表是Student */ FOREIGN KEY (Cno) REFERENCES Course(Cno) /* 表级完整性约束条件, Cno是外码,被参照表是Course*/ );
数据类型
数据类型 |
---|
CHAR(n) |
VARCHAR(n) |
INT |
SMALLINT |
NUMERIC(p, d) |
REAL |
Double Precision |
FLOAT(n) |
DATE |
TIME |
模式与表
DBA
用户可以设置搜索路径,然后定义基本表
SET search_path TO “S-T”,PUBLIC;
Create table Student(......);
修改基本表
ALTER TABLE <表名> ADD <新列名> <数据类型> 完整性约束 DROP <完整性约束名> ALTER COLUMN<列名> <数据类型>;
ALTER TABLE Student ADD S_entrance DATE;
ALTER TABLE Student ALTER COLUMN Sage INT;
ALTER TABLE Course ADD UNIQUE(Cname);
删除基本表
DROP TABLE <表名> [RESTRICT| CASCADE];
一、建立索引
语句格式
CREATE [UNIQUE] [CLUSTER] INDEX <索引名> ON <表名> ( <列名> [<次序>], <列名> [<次序>], <列名> [<次序>], );
CREATE CLUSTER INDEX Stusname ON Student(Sname);
CREATE UNIQUE INDEX Stusno ON Student(Sno);
CREATE UNIQUE INDEX Coucno ON Course(Cno);
CREATE UNIQUE INDEX SCno ON SC(Sno ASC,Cno DESC)
CLUSTER
为聚簇索引(指索引项的顺序与表中记录的物理顺序一致的索引组织)。一个表只有一个。UNIQUE
表示唯一索引。二、删除索引
DROP INDEX <索引名>;
一、 选择表中的若干列
-- 小写字母
SELECT Sname,'Year of Birth:', 2004-Sage, LOWER(Sdept) FROM Student;
-- 列别名
SELECT Sname NAME, 'Year of Birth:' BIRTH, 2000-Sage BIRTHDAY, LOWER(Sdept) DEPARTMENT FROM Student;
二、选择表中的若干元组
1.消除取值重复的行,如果没有指定DISTINCT
关键词,则缺省为ALL
SELECT DISTINCT Sno FROM SC;
查询条件 | 谓词 |
---|---|
比较 | =,>,<,>=,<=,!=,<>,!>,!<,NOT |
确定范围 | BETWEEN AND |
确定集合 | IN |
字符匹配 | LIKE |
空值 | IS NULL, IS NOT NULL |
多重条件(逻辑运算) | AND, OR, NOT |
WHERE Sage BETWEEN 20 AND 23;
WHERE Sage NOT BETWEEN 20 AND 23;
WHERE Sdept IN ( 'IS','MA','CS' );
WHERE Sdept NOT IN ( 'IS','MA','CS' );
-- 匹配串为固定字符串
WHERE Sno LIKE '200215121';
-- 匹配串为含通配符的字符串 (% 、_)
WHERE Sname LIKE '刘%';
WHERE Sname LIKE '欧阳_ _';
-- 使用换码字符将通配符转义为普通字符
WHERE Cname LIKE 'DB\_Design' ESCAPE '\';
-- ESCAPE '\' 表示“ \” 为换码字符
三、ORDER BY子句
ASC
:排序列为空值的元组最后显示DESC
:排序列为空值的元组最先显示 四、聚集函数
COUNT
SUM
AVG
MAX
MIN
SELECT COUNT(*) SELECT COUNT(DISTINCT Sno)
五、GROUP BY子句
SELECT Cno, COUNT(Sno) FROM SC GROUP BY Cno;
SELECT Sno FROM SC GROUP BY Sno HAVING COUNT(*) >3;
HAVING
短语与WHERE
子句的区别:
WHERE
子句作用于基表或视图,从中选择满足条件的元组HAVING
短语作用于组,从中选择满足条件的组连接查询:同时涉及多个表的查询
嵌套循环法(NESTED-LOOP
)
首先在表1中找到第一个元组,然后从头开始扫描表2,逐一查找满足连接件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组。
表2全部查找完后,再找表1中第二个元组,然后再从头开始扫描表2,逐一查找满足连接条件的元组,找到后就将表1中的第二个元组与该元组拼接起来,形成结果表中一个元组。
一、等值与非等值连接查询
等值连接:连接运算符为=
SELECT Student.*,SC.* FROM Student,SC WHERE Student.Sno = SC.Sno;
自然连接:等值连接中把目标列中重复的属性列去掉
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade FROM Student,SC WHERE Student.Sno = SC.Sno;
二、自身连接
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 OUT JOIN SC ON (Student.Sno=SC.Sno);
四、复合条件连接
复合条件连接:
WHERE
子句中含多个连接条件
嵌套查询概述
SELECT-FROM-WHERE
语句称为一个查询块WHERE
子句或HAVING
短语的条件中的查询称为嵌套查询SELECT Sname /*外层查询/父查询*/ FROM Student WHERE Sno IN ( SELECT Sno /*内层查询/子查询*/ FROM SC WHERE Cno= ' 2 ');
子查询的限制
ORDER BY
子句SQL
语言的结构化不相关子查询
相关子查询
嵌套查询的形式
一、带有IN
谓词的子查询
-- 将第一步查询嵌入到第二步查询的条件中 | -- 用自身连接完成:
|
SELECT Sno, Sname, Sdept | SELECT S1.Sno, S1.Sname, S1.Sdept FROM Student | FROM Student S1, Student S2 WHERE Sdept IN ( | WHERE S1.Sdept = S2.Sdept AND S2.Sname = '刘晨';
SELECT Sdept | FROM Student | WHERE Sname= '刘晨' | ); |
|
-- 此查询为不相关子查询。 |
二、带有比较运算符的子查询
[例41]找出每个学生超过他选修课程平均成绩的课程号。
SELECT Sno, Cno FROM SC x WHERE Grade >= ( SELECT AVG(Grade) FROM SC y WHERE y.Sno = x.Sno );
此查询为相关子查询。
三、带有ANY
(SOME
)或ALL
谓词的子查询
[例42] 查询其他系中比计算机科学某一学生年龄小的学生姓名和年龄
SELECT Sname, Sage FROM Student WHERE Sage < ANY ( SELECT Sage FROM Student WHERE Sdept= ' CS' ) AND Sdept <> 'CS ' ; /*父查询块中的条件 */
四、带有EXISTS
谓词的子查询
1.EXISTS
谓词
EXISTS
谓词的子查询不返回任何数据,只产生逻辑真值true
或逻辑假值false
。WHERE
子句返回真值WHERE
子句返回假值EXISTS
引出的子查询,其目标列表达式通常都用*
,因为带EXISTS
的子查询只返回真值或假值,给出列名无实际意义[例44]查询所有选修了1号课程的学生姓名。
思路分析:
本查询涉及Student和SC关系
在Student中依次取每个元组的Sno值,用此值去检查SC关系
若SC中存在这样的元组,其Sno值等于此Student.Sno值,并且其Cno= ‘1’,则取此Student.Sname送入结果关系
用嵌套查询 | 用连接运算
SELECT Sname | SELECT Sname FROM Student | FROM Student, SC WHERE EXISTS ( | WHERE Student.Sno=SC.Sno AND SC.Cno= '1';
SELECT * | FROM SC | WHERE Sno=Student.Sno AND Cno= '1' | ); |
不同形式的查询间的替换
EXISTS
或NOT EXISTS
谓词的子查询不能被其他形式的子查询等价替换IN
谓词、比较运算符、ANY
和ALL
谓词的子查询都能用带EXISTS
谓词的子查询等价替换用EXISTS
/NOT EXISTS
实现全称量词(难点)
SQL
语言中没有全称量词(For all)[例39]查询与“刘晨”在同一个系学习的学生。
-- 可以用带EXISTS谓词的子查询替换:
SELECT Sno,Sname,Sdept FROM Student S1 WHERE EXISTS ( SELECT * FROM Student S2 WHERE S2.Sdept = S1.Sdept AND S2.Sname = '刘晨' );
[例46] 查询选修了全部课程的学生姓名。
SELECT Sname FROM Student WHERE NOT EXISTS ( SELECT * FROM Course WHERE NOT EXISTS ( SELECT * FROM SC WHERE Sno= Student.Sno AND Cno= Course.Cno ) );
集合操作的种类
UNION
INTERSECT
EXCEPT
参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同
[例48] 查询计算机科学系的学生及年龄不大于19岁的学生。
SELECT * FROM Student WHERE Sdept= 'CS' UNION SELECT * FROM Student WHERE Sage<=19;
UNION
:将多个查询结果合并起来时,系统自动去掉重复元组。
UNION ALL
:将多个查询结果合并起来时,保留重复元组
SELECT [ALL|DISTINCT] FROM WHERE GROUP BY HAVING ORDER BY
两种插入数据方式
一、插入元组
INSERT INTO Student (Sno, Sname, Ssex, Sdept, Sage) VALUES ('200215128', '陈冬', '男', 'IS', 18);
INSERT INTO Student VALUES ('200215126', '张成民', '男', 18, 'CS');
二、插入子查询结果
INSERT INTO Dept_age(Sdept,Avg_age) SELECT Sdept,AVG(Sage) FROM Student GROUP BY Sdept;
UPDATE Student SET Sage = 22 WHERE Sno= '200215121';
[例7] 将计算机科学系全体学生的成绩置零。
UPDATE SC SET Grade=0 WHERE 'CS'= ( SELETE Sdept FROM Student WHERE Student.Sno = SC.Sno );
[例10] 删除计算机科学系所有学生的选课记录。
DELETE FROM SC WHERE 'CS' = ( SELETE Sdept FROM Student WHERE Student.Sno=SC.Sno );
ORDER BY
子句和DISTINCT
短语WITH CHECK OPTION
表示对视图进行UPDATE
,INSERT
和DELETE
操作时要保证更新、插入或删除的行满足视图定义中的谓词条件(即子查询中的条件表达式)。CREATE VIEW IS_Student AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept= 'IS';
-- 基于多个基表的视图
[例3] 建立计算机系选修了1号课程的学生视图。
CREATE VIEW CS_S1(Sno, Sname, Grade) AS SELECT Student.Sno, Sname, Grade FROM Student, SC WHERE Sdept= 'CS' AND Student.Sno=SC.Sno AND SC.Cno= '1';
二、删除视图
DROP VIEW <视图名>;
RDBMS
实现视图查询的方法–视图消解法(View Resolution)
INSERT
)、删除(DELETE
)和修改(UPDATE
)数据。由于视图是不实际存储数据的虚表,