SQL语法

有时候方向比努力更重要! / 2023-05-10 / 原文

创建基本表

创建基本表要对表进行命名,定义表的每个列,定义表的完整性约束条件,我们使用CREATE TABLE语句创建基本表

CREATE TABLE <表名>
(<列名> <数据类型> [DEEAULT<缺省值>] [列级约束定义],
<列名> <数据类型> [DEEAULT<缺省值>] [列级约束定义],
<列名> <数据类型> [DEEAULT<缺省值>] [列级约束定义],
...,
[<表级约束定义>],...,<表级约束定义>);

1、表名、列名均是由我们自己去定义的
2、数据类型即sql语言中给定的几种数据类型
3、缺省值是以后我们向数据库该的表中插入元素时,假如我们空缺了这一项,就会填上我们设置的缺省值
4、列级约束定义是对当前列的约束条件

[CONSTRAINT <约束名>] <列约束>

列约束包括以下几种:
NOT NULL:不允许该列取空值;不加NOT NULL限制时,该列可以取空值
PRIMARYKEY:指明该列为主码,其值非空、唯一
UNIQUE:该列上的值唯一,说明改列为候选码
CHECK(<条件>):指明该列的值必须满足的条件,<条件>为一个bool表达式

排序和分组

排序

ORDER BY子句可以将查询结果按一定的次序显示.
形式:

ORDER BY <排序列> [ASC | DESC]{, <排序列> [ASC | DESC]}

1、<排序列>是必须出现在SELECT语句中的属性名。
2、ORDER BY语句可以有一个或多个排序列,中间用逗号隔开。每个排序列都可以单独指定升序还是降序排列,缺省时为升序。
查询每位学生的每门课程的成绩,按成绩降序排序。

SELECT *
FROM SC
WHERE Cno = 'CS202'
ORDER BY Grade DESC;

3、聚集函数

统计元组个数
COUNT([ALL|DISTINCT]*)	
统计一列中值的个数
COUNT([ALL | DISTINCT] 列名)
计算一列中值的个数
SUM([ALL | DISTINCT] 列名)
AVG([ALL | DISTINCT] 列名)
MAX([ALL | DISTINCT] 列名)
MIN([ALL | DISTINCT] 列名)

分组

分组的关系和聚集函数的关系很大
GROUP BY语句

GROUP BY<分组列>[HAVING <分组选择条件>]

分组语句细化了聚集函数的作用范围
HAVING短语用来过滤掉不满足的<分组选择条件>的分组,缺省时等价于HAVING TRUE
<分组选择条件>类似于WHERE子句的查询条件,只不过WHERE子句中不允许出现聚集函数

eg:查询每个学生的平均成绩,并输出平均成绩大于85的学生的学号和平均成绩

SELECT Sno, AVG(Grade)
FROM SC
GROUP BY Sno HAVING AVG(Grade) > 85;

对于带GROUP BY子句的SELECT语句,SELECT子句中的结果列必须是GROUP BY子句中的<分组列>或聚集函数。

连接查询

Q:查询阿杜选修数据库系统原理课程的成绩?

当查询需要的信息或者查询条件涉及的属性分布在多个表中时,需要进行链接查询

1、SQL支持连接查询,允许FROM子句中包括多个表
2、当FROM子句中包含多个表时,相当于求这些表的笛卡尔积
3、可以在WHERE子句中说明连接条件,并通过SELECT子句选取所需要的属性来实现各种连接
eg:查询学号为201705001的学生的各科成绩,对每门课程显示课程名和成绩

SELECT Cname, Grade
FROM SC, Course
WHERE SC.Cno = Course.Cno AND Sno = '2017050001'

eg:查询每个学生的平均成绩,并输出平均成绩大于85的学生的学号、姓名和平均成绩

SELECT Student.Sno, Sname, AVG(Grade)
FROM SC, Students
WHERE Student.Sno, Sname
HAVING AVG(Grade) > 85;w

嵌套查询

SQL是一种结构化查询语言,他允许将一个查询作为子查询嵌套在另一个SELECT语句中

比较常见的嵌套是将查询结果嵌套在WHERE或HAVING语句中,子查询不能用ORDER BY语句,只有最终查询结果才能用ORDEFR BY语句

IN引出的子查询

<元组>[NOT]IN<子查询>

eg:查询和林艳在同一专业学习的女同学的学号和姓名

SELECT Sno, Sname
FROM Students
WHERE Sex = '女' AND Speciality IN
(
SELCET Speciality
FROM Students
WHERE Sname = '林艳');

下面是先找到林艳的专业,然后将此专业作为查询条件

集合的比较引出的查询

SQL语言允许将一个元素与子查询的结果集进行比较。
形式

<值表达式> Θ ALL | SOME | ANY <子查询>

其中<值表达式>通常是属性,Θ是比较运算符。SOME与ANY含义相同。早期只有ANY但是和英语上的any容易混淆,现在多用SOME。当<子查询>的结果为单个值时,ALL、SOME和ANY可以省略。
eg:
查询比软件工程专业所有学生都小的其他专业的学生的学号、姓名、专业和出生日期

SELECT Sno, Sname, Speciality, year(BIrthday)
From Students
WHERE Speciality <>'软件工程' AND year(Birthday) > ALL(SELECT year (Birthday)
FROM Students
WHERE Speciality = '软件工程');

ALL 可以与聚集函数实现的查询互换

SELECT Sno, Sname, Speciality, year(Birthday)
FROM Students
WHERE Speciality<> '软件工程' AND 
year(Birthday) > (SELECT MAX(year(Birthday)))
	FROM Students
	WHERE Speciality = '软件工程');

image

存在量词引导的子查询

形式:

EXISTS <子查询>
子查询的SELECT子句的形式为SELECT*。EXISTS<子查询>为真,当且仅当<子查询>的结果非空(至少包含一个元组)

EXISTST是根据外层查询的每个元组依次取与内层查询的结果比较看是否为空,若非空则为真输出,反之则不输出,这是一个相关子查询。
这里我们可以把查询分为两种,一种是相关子查询,一种是不相关子查询。相关子查询就是内层查询依赖于外层查询,不相关子查询就是外层查询不依赖于内层查询

感觉NOT EXISTS这里很绕还没有搞清楚,搞清楚再回来补这一点的内容和例子

数据更新

插入

1、向基本表中插入单个元组

INSERT INTO T [(A1, ..., Ak)] VALUE(c1, ..., ck)

eg:
向Students表中添加一条这样的记录

INSERT INTO Students
VALUES ('201716010', '司马相如', '男', 1997-01-28, '2017', '计算数学', 'MATh')

A1,A2...可以不按顺序,只要与下面的值对应就可以,A1,A2等也可以省略,但这是下面的内容则必须按顺序

2、插入查询结果
想基本表中插入单个元组一般用于数据的输入,我们有时候还想将查询结果插入到一个基本表中。插入查询结果的语句的基本形式:

INSERT INTO T [(A1, A2, ..., Ak)]
<查询表达式>

T通常是基本表,也可以是视图, A1,...,Ak是T的属性,<查询表达式>通常是一个SELECT语句

eg:
信息工程学院要为本院每位教师办理一个校内就餐卡,直接用教师号作为主持人的编号,并预存100元,可以用INSERT语句插入到基本表中

INSERT INTO Cardinf(Card-no, Name, Balance)
SELECT Tno, Tname, 100.00
FROM Teachers
WHERE Dno = 'IE';

注意常量100.00出现在SELECT中。这使得查询结果的每个元组的第3列均取常量100.00。

修改

删除

当关系表中的某些记录已经不再需要时,可以使用DELETE语句进行删除。

DELETE FROM T
	[WHERE <删除条件>]

T通常是基本表,但也可以是某些视图
<删除条件>与SELECT语句中的查询条件