概述
设有学生-课程数据库,内含三个表:
学生表:Student(Sno,Sname,Ssex,Sage,Sdept)
课程表:Course(Cno,Cname,Cpno,Ccredit)
学生选课表:SC(Sno,Cno,Grade)
一、数据定义
(一)模式的定义与删除
1、定义模式
CREATE SCHEMA <模式名> AUTHORIZATION <用户名>
如果没有指定<模式名>,那么<模式名>隐含为<用户名>
例如:为用户WANG定义一个学生-课程模式S-T
CREATE
SCHEMA**"S-T"** AUTHORIZATION **WANG**//常规写法
CREATE
SCHEMA
AUTHORIZATION **WANG**
// <模式名>隐含为用户名WANG
一个模式下可以创建多个基本表、视图和索引等数据库对象
例如:为用户ZHANG创建一个模式TEST,并在其中定义一个表TAB1
CREATE
SCHEMA TEST AUTHORIZATION ZHANG
CREATE
TABLE TAB1(
COL1 INT,
COL2 CHAR(20),
COL3 DECIMAL(5,2)
);
2、删除模式
DROP SCHEMA <模式名><CASCADE|RESTRICT>
其中CASCADE和RESTRICT两者必选其一。
CASCADE(级联)表示将该模式中所有数据库对象全部删除。
RESTRICT(限制)表示如果该模式中已经定义了下属的数据库对象(如表、视图等),则拒绝该删除语句的执行,只有当该模式下没有任何下属对象时才能执行DROP SCHEMA 语句。
(二)基本表的定义、删除与修改
1、定义基本表
如图定义一个“学生”表Student
CREATE TABLE Student
(Sno CHAR(9) PRIMARY KEY,
//列级完整性约束条件,Sno是主码
Sname CHAR(20) UNIQUE,
//Sname取唯一值
Ssex CHAR(2),
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
);
2、数据类型
常用数据类型表
数据类型 | 含义 |
---|---|
char(n) ,character(n) | 长度为n的定长字符串 |
varchar(n),charactervarying(n) | 最大长度为n的变长字符串 |
clob | 字符串大对象 |
blob | 二进制大对象 |
int,integer | 长整数(4字节) |
smallint | 短整数(2字节) |
bigint | 大整数(8字节) |
numeric(p,d) | 定点数,p位数字(不包括符号、小数点)组成,小数点后面有d位数字 |
float(n) | 可选精度的浮点数,精度至少为n位数字 |
boolean | 逻辑布尔量 |
date | 日期 格式为yyyy-mm-dd 例如2022-10-15 |
time | 时间,包含一日的时分秒,格式为HH:MM:SS |
3、修改基本表
ALERT TABLE <表名>
[ADD [COLUMN] <新列名><数据类型>[完整性约束]]
[ADD<表级完整性约束>]
[DROP [COLUMN]<列名>[CASCADE|RESTRICT]]
[DROP CONSTRAINT<完整性约束名>[CASCADE|RESTRICT]]
[ALERT COLUME<列名><数据类型>];
例如:向Student表中添加”入学时间“列,其数据类型为日期型
ALERT TABLE Student ADD S_entrance DATE;
例如:将年龄的数据类型由字符型改为整数
ALERT TABLE Student ALERT COLUMN Sage INT;
例如:增加课程名称必须取唯一值的约束条件
ALERT TABLE Course ADD UNIQUE(Cname);
4、删除基本表
当某个基本表不再需要时,可以用DROP TABLE语句删除
DROP TABLE<表名> [RESTRICT|CASCADE];
(三)索引的建立与消除
1、建立索引
CREATE [UNIQUE] [CLUSTER] INDEX <索引名> ON <表名>(<列名>[<次序>]);
例如:为学生-课程数据库中的Student、Course和SC三个表建立索引。其中Student表按照学号升序建立唯一索引,Course表按照课程号升序建立唯一索引,SC表按学号升序和课程号降序建立唯一索引。
CREATE UNIQUE INDEX Stusno ON Student(Sno);
CREATE UNIQUE INDEX Coucno ON Course(Cno);
CREATE UNIQUE INDEX SCno ON SC(Sno ASC,Cno DESC);
2、修改索引
重命名语句
ALERT INDEX<旧索引名> RENAME TO <新索引名>;
3、删除索引
DROP INDEX<索引名>;
二、数据查询
(一)单表查询
1、选择若干列
SELECT <目标列表达式> FROM <表名>
(1) 查询指定列:查询学生的姓名和学号
SELECT Sname,Sno FROM Student;
(2) 查询全部列:查询全体学生记录
SELECT * FROM Student;
(3) 查询经过计算的值:查询全体学生姓名及其出生年份
SELECT子句的<目标列表达式>也可以是表达式、字符串常量、函数等
SELECT Sname,2022-Sage FROM Student;
亦可修改输出结果的列标题:
SELECT Sname 姓名,Sno 学号 FROM Student;
2、选择若干元组
(1)查询元组
SELECT [ALL|DISTINCT] <目标列表达式> FROM SC
DISTINCT用于去除重复行,而ALL则保留取值重复的行,没有关键词时默认是ALL
(2)查询满足条件的元组
查询满足条件的元组可以用WHERE子句实现,其常用查询条件如下表:
查询条件 | 谓词 |
---|---|
比较 | =,>,<,>=,<=,!= 等比较运算符 |
确定范围 | BETWEEN AND,NOT BETWEEN AND |
确定集合 | IN,NOT IN |
字符匹配 | LIKE,NOT LIKE |
空值 | IS NULL,IS NOT NULL |
多重条件 | AND,OR,NOT |
1. 比较大小
查询计算机科学系的学生名单
SELECT Sname FROM Student
WHERE Sdept='CS';
查询考试成绩不及格学生学号
SELECT DISTINCT Sno FROM SC
WHERE Grade<60;
2. 确定范围
查询年龄不在20~23之间的学生姓名
SELECT Sname FROM Student
WHERE Sage NOT BETWEEN 20 AND 23;
3. 确定集合
查询既不是计算机科学系、数学系、也不是信息系的学生的姓名和性别
SELECT Sname,Ssex FROM Student
WHERE Sdept NOT IN ('CS','MA','IS');
4. 字符匹配
通配符 % 和 _
%代表任意长度的字符串,如a%b代表以a开头,以b结尾的任意长度字符串。
_代表任意单个字符,如a_b代表以a开头、以b结尾的长度为3的任意字符串
查询所有不姓刘的学生的姓名、学号和性别
SELECT Sname,Sno,Ssex FROM Student
WHERE Sname NOT LIKE '刘%';
查询名字中第二个字为“阳”的学生的姓名、学号和性别
SELECT Sname,Sno,Ssex FROM Student
WHERE Sname LIKE '_阳%';
如果用户要查询的字符串本身就含有通配符,则需要ESCAPE对通配符进行转义
查询DB_Design 课程的课程号和学分
SELECT Cno,Ccredit FROM Student
WHERE Cname LIKE 'DB_Design' ESCAPE'';
ESCAPE代表‘’为换码字符,这样后面的‘_’不再是通配符,而是一个普通字符
5. 涉及空值查询
查询所有有成绩的学生学号和课程号
SELECT Sno,Cno FROM SC
WHERE Grade IS NOT NULL;
6. 多重条件查询
逻辑运算符AND和OR可以连接多个查询条件。AND的优先级高于OR,但是用户可以用括号改变优先级。
查询计算机科学系年龄在20岁以下的学生姓名
SELECT Sname FROM Student
WHERE Sdept='CS' AND Sage<20;
3、ORDER BY子句
ORDER BY 子句可以对查询结果按照一个或者多个属性列的升序(ASC)或降序(DESC)排列,默认值为升序
查询全体学生情况,查询结果按所在系的序号升序排列,同一系中的学生按年龄降序排列
SELECT * FROM Student
ORDER BY Sdept Sage DESC;
4、聚集函数
为进一步方便用户,增强检索功能,SQL提供了许多聚集函数
聚集函数代码 | 实现功能 |
---|---|
COUNT(*) | 统计元组个数 |
COUNT( [DISTINCT / ALL] <列名> ) | 统计一列值的个数 |
SUM( [DISTINCT / ALL] <列名> ) | 计算一列值的总和(此列必须是数值型) |
AVG( [DISTINCT / ALL] <列名> ) | 计算一列值的平均值(此列必须是数值型) |
MAX( [DISTINCT / ALL] <列名> ) | 求一列中的最大值 |
MIN( [DISTINCT / ALL] <列名> ) | 求一列中的最小值 |
查询学生201215012选修课程的总学分数
SELECT SUM(Ccredit) FROM SC,Course
WHERE Sno='201215012' AND SC.Cno=Course.Cno
WHERE子句中不能用聚集函数作为条件表达式。聚集函数只能用于SELECT子句和GROUP BY子句中的HAVING子句
5、GROUP BY子句
GROUP BY 子句将查询结果按某一列或多列的值分组,值相等的为一组。
例如:求各个课程号及相应的选课人数
SELECT Cno,COUNT(Sno) FROM SC
GROUP BY Cno;
如果分组以后还要按照一定条件对这些组进行筛选,最终只输出满足指定条件的组,则可以用HAVING短语指定筛选条件
查询选修了三门以上课程的学生学号
SELECT Sno FROM SC
GROUP BY Sno
HAVING COUNT(*)>3;
上例先用GROUP BY子句按Sno进行分组,再用聚集函数COUNT对每一组进行计数;HAVING短语给出了选择组的条件,只有满足条件(即元组个数>3,表示此学生选修的课程超过3门)的组才会被选出来
WHERE子句和HAVING短语的区别在于作用对象不同。前者作用于基本表或者视图,后者作用于组。
(二)连接查询
若一个查询同时涉及两个及以上的表,则称为连接查询。
1、等值连接和非等值连接
查询选修2号课程且成绩在90分以上的所有学生的学号和姓名
SELECT Student.Sno,Sname FROM Student,SC
WHERE Student.Sno=SC.Sno AND
//连接谓词
SC.Cno='2' AND SC.Grade>90;
//其他限定条件
2、自身连接
一个表与自身连接,称为表的自身连接
查询一门课程的间接先修课(即先修课的先修课)
首先要为Course表取两个别名,一个是FIRST,一个是SECOND
SELECT FIRST.Cno,SECOND.Cpno
FROM Course FIRST,Course SECOND
WHERE FIRST.Cpno=SECOND.Cno;
3、外连接
保留悬浮元组则使用外连接。左外连接列出左边关系中的所有元组,右外连接列出右边关系中的所有元组。
例如:列出学生的基本情况和选课情况。(没选也要列)
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student LEFT OUTER JOIN SC ON(Student.Sno=SC.Sno);
4、多表连接
两个表以上的连接称为多表连接。
例如:查询每个学生的学号、姓名、选修的课程名及成绩
SELECT Student.Sno,Sname,Cname,Grade
FROM Student,SC,Course
WHERE Student.Sno=SC.Sno AND SC.Sno=Course.Cno;
(三)嵌套查询
一个SELECT-FROM-WHERE语句被称为一个查询块。将一个查询块嵌套在另一个查询块的WHERE子句或者HAVING短语的条件中的查询称为嵌套查询。
1、带有IN谓词的子查询
查询与“刘晨”在同一个系学习的学生
SELECT Sno,Sname,Sdept FROM Student
WHERE Sdept IN
(SELECT Sdept
FROM Student
WHERE Sname='刘晨');
这种子查询的查询条件不依赖于父查询的,也被称为不相关子查询
2、带有比较运算符的子查询
找出每个学生超过他自己选修课程平均成绩的课程号
SELECT Sno,Cno
FROM SC x
WHERE Grade>=(SELECT AVG(Grade)
FROM SC y
WHERE y.Sno=x.Sno);
上例中x和y是表SC的别名,子查询与父查询相关称为相关子查询。
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<
(SELECT MAX(Sage)
FROM Student
WHERE Sdept='CS')
AND Sdept!='CS'
4、带有EXISTS谓词的子查询
EXISTS代表存在量词 ∃。带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或者逻辑假值“false”。
查询选修了1号课程的学生姓名
SELECT Sname FROM Student
WHERE EXISTS
(SELECT *
FROM SC
WHERE Sno=Student.Sno AND Cno='1');
SQL没有全称量词和其他逻辑蕴涵谓词,但可以等价转换
例如:查询至少选修了学生201215122选修的全部课程的学生号码
用p表示谓词:学生201215122选修了课程y
用q表示谓词:学生x选修了y
可以理解为:不存在课程y,使得学生201215122选修了y,但x没有选修y
SELECT DISTINCT Sno
FROM SC SCX
WHERE NOT EXISTS
(SELECT *
FROM SC SCY
WHERE SCY.Sno='201215122' AND
NOT EXISTS
(SELECT *
FROM SC SCZ
WHERE SCZ.Sno=SCX.Sno AND
SCZ.Cno=SCY.Cno));
(四)集合查询
集合操作主要包括并操作UNION,交操作INTERSECT和差操作EXCEPT。
参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同。
查询计算机科学系的学生 与 年龄不大于19岁的学生的交集
SELECT * FROM Student
WHERE Sdept='CS'
INTERSECT
SELECT * FROM Student
WHERE Sage<19;
(五)基于派生表的查询
子查询不仅可以出现在WHERE子句中,还可以出现在FROM语句中,这时子查询生成的临时派生表成为主要的查询对象。
例如:找出每个学生超过他自己选修课程平均成绩的课程号
SELECT Sno,Cno
FROM SC,(SELECT Sno,Avg(Grade) FROM SC GROUP BY Sno)
AS Avg_sc(avg_sno,avg_grade)
WHERE SC.Sno=Avg_sc.avg_sno and SC.Grade>=Avg_sc.avg_grade
上述代码中,FROM子句中的子查询将生成一个派生表Avg_sc。该表由avg_sno和avg_grade两个属性组成,记录了每个学生的学号及平均成绩,主查询将SC表与Avg_sc按学号相等进行连接,选出选课成绩大于其平均成绩的课程号。
通过FROM子句生成派生表时,AS关键字可以省略,但必须为派生关系指定一个别名
三、数据更新
(一)插入数据
1、插入元组
INSERT
INTO <表名> [<属性列1>,<属性列2>,<属性列3>]
VALUES(<常量1>,<常量2>,<常量3>);
例如:将学生小明的成绩插入到Student表中
INSERT
INTO Student
VALUES('201215127','小明','男','18','CS');
2、插入子查询结果
INSERT
INTO <表名> [<属性列1>,<属性列2>,<属性列3>]
子查询
例如:对每一个系,求学生的平均年龄,并把结果存入数据库
CREATE TABLE Dept_age
(Sdept CHAR(15)
Avg_age SMALLINT);
INSERT
INTO Dept_age
SELECT Sdept,AVG(Sage)
FROM Student
GROUP BY Sdept;
(二)修改数据
UODATE <表名>
SET <列名>=<表达式>
WHERE <条件>;
1、修改某一元组的值
例如:将学生201215121的年龄改为22岁
UODATE Student
SET Sage=22
WHERE Sno='201215121';
2、修改多个元组的值
例如:将所有学生的年龄增加1岁
UODATE Student
SET Sage=Sage+1;
3、带子查询的修改语句
子查询可以嵌套在UPDATE语句中,用于构造修改的条件
例如:将计算机科学系全体学生的成绩清零
UODATE SC
SET Grade=0
WHERE Sno IN
(SELECT Sno
FROM Student
WHERE Sdept='CS');
(三)删除数据
1、删除某一元组的值
例如:删除学号为201215128的学生记录
DELETE
FROM Student
WHERE Sno='201215128';
2、删除多个元组的值
例如:删除所有学生选课记录
DELETE
FROM SC;
3、带子查询的删除语句
例如:删除计算机科学系所有学生的选课记录
DELETE
FROM SC
WHERE Sno IN
(SELECT Sno
FROM Student
WHERE Sdept='CS');
最后
以上就是奋斗汉堡为你收集整理的SQL——数据各项操作代码实现一、数据定义二、数据查询三、数据更新的全部内容,希望文章能够帮你解决SQL——数据各项操作代码实现一、数据定义二、数据查询三、数据更新所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复