1
大学信息技术基础
1.11.5 8.5 关系数据库标准语言SQL

8.5 关系数据库标准语言SQL

8.5.1SQL 概述

结构化查询语言(Structured Query Language,SQL )是目前使用最广泛的关系数据库的标准查询语言。SQL 具有以下特点。

1.一体化

SQL 是一种一体化的语言,它包括数据定义、数据查询、数据操纵和数据控制等多方面的功能,可完成数据库活动中的全部工作。SQL 同时集成了数据定义语言、数据操纵语言和数据控制语言。

2.高度非过程化

SQL 是高度非过程化语言。 在进行数据操作时,只要用户指出“做什么”,而不必指明“怎么做”,具体的实现则是数据库管理系统的任务。

3.面向集合的操作方式

SQL 语言采用的是集合操作方式,其操作对象和结果都可以是元组的集合。

4.多种使用方式

SQL 既是自含式语言,又是嵌入式语言。

作为自含式语言,它能够独立地用于联机交互,用户可以在终端键盘上直接键入SQL 命令对数据库进行操作。 作为嵌入式语言,SQL 能够嵌入到高级语言(如C、VB)程序中,供程序员设计程序时使用。 而在两种使用方式下,SQL 的语法结构基本上是一致的。 这种以统一的语法结构提供两种使用方式的做法,为用户提供了极大的灵活性与方便性。

5.语言简洁,易学易用

SQL 语言非常简洁,完成其核心功能只用到了九个动词:数据定义(CREATE、DROP、ALTER)、数据查询(SELECT)、数据操纵(INSERT、UPDATE、DELETE)、数据控制(GRANT、REVOKE)。SQL 接近英语口语,因此容易学习,容易使用。

8.5.2SQL 数据查询语句

数据查询语句SELECT-SQL 是SQL 的核心语句,具有强大的查询功能,熟练掌握SELECT-SQL 语句的一部分就可以实现大部分的数据库查询工作。

SELECT语句常用格式如下:

SELECT[ALL|DISTINCT] 〈列名表〉

FROM〈表名〉 [,〈表名〉]

[WHERE〈条件表达式〉]

[GROUP BY〈列名表〉 [HAVING〈条件表达式〉]]

[ORDER BY〈列名表〉 [ASC|DESC]...]

说明:

(1)SELECT子句指明要显示的字段。 选项DISTINCT将删除所选字段的重复记录,默认为ALL,即允许重复数据集合出现。

(2)FROM子句指定了表名,表中包含了SELECT子句所指定的字段。

(3)WHERE子句指明了筛选条件,用于选择满足条件的记录。

(4)GROUP子句将结果按〈列名表〉的值进行分组,该属性列值相等的元组为一个组,每个组产生结果表中的一条记录。 通常,在每组中作用聚集函数。 若带HAVING短语,则只有满足指定条件的组才输出。

(5)ORDER子句将结果按〈列名表〉的值升序或降序排列,选项ASC为升序, DESC为降序,默认为升序。

8.5.3 SELECT语句的应用示例

下面以6.2.2中的教学管理数据库为例,说明SELECT如何实现简单查询、条件查询和自然连接查询等。

1.简单查询

(1)查询所有列

例8.4:查询“学生”表中所有的字段信息。

SELECT*

FROM学生;

(2)查询指定列

例8.5:查询“学生”表中所有学生的“姓名”“性别”“生源”和“政治面貌”信息。

SELECT姓名,性别,生源,政治面貌

FROM学生;

(3)查询计算列的值

例8.6:查询“教师”表中所有教师的“教师编号”“姓名”“职称”“工资”和“纳税金额”[假设纳税金额=(工资-2000)*5%)]信息。

SELECT教师编号,姓名,职称,工资,(工资-2000)*0.05AS纳税金额

FROM教师;

说明:使用AS为返回结果指定

别名。

(4)查询指定列的唯一值

例8.7:查询“学生”表中所有的“生源”地(重复值只保留一个)。

SELECT DISTINCT生源

FROM学生;

2.条件查询

在SELECT-SQL 语句中使用WHERE子句设置查询数据的筛选条件。

(1)使用比较运算符

例8.8:查询“学生”表中所有生源地非“福建”的学生的姓名和性别。

SELECT姓名,性别

FROM学生

WHERE生源〈〉“福建“;

说明:SQL 中使用的比较运算符有=(等于)、〈(小于)、〉(大于)、〉=(大于等于)、〈=(小于等于)、〈〉(不等于)。

(2)使用逻辑运算符

例8.9:查询“学生”表中1998年出生的男生的“学号”“姓名”“性别”和“出生日期”信息。

SELECT学号,姓名,性别,出生日期

FROM学生

WHERE性别=“男“ANDYear(出生日期)=1998;

说明:本例使用了求年份函数year(日期)。

例8.10:查询“学生”表中所有“团员”和“党员”的“姓名”“性别”“出生日期”和“政治面貌”信息。

SELECT姓名,性别,出生日期,政治面貌

FROM学生

WHERE政治面貌=“党员“Or政治面貌=“团员“;

例8.11:查询“学生”表中所有“团员”和“党员”且性别为男的“姓名”“性别”“出生日期”和“政治面貌”信息。

SELECT姓名,性别,出生日期,政治面貌

FROM学生

WHERE(政治面貌=“党员“Or政治面貌=“团员“) And性别=“男“;

说明:SQL 中使用的逻辑运算符有AND(与)、OR(或)、NOT(非)。

(3)使用LIKE运算符

LIKE运算符为字符串匹配运算符,可对字符型数据进行模糊匹配。

其使用格式如下:

〈列名〉[NOT] LIKE“〈字符串常量〉“

字符串常量中除了可含有普通字符以外,还可包含以下两个通配符。

*:表示任意多个字符或汉字。

?:表示任意一个字符或汉字。

NOTLIKE是LIKE的否定运算。

例8.12:查询“学生”表中所有姓名中含有“龙”的学生信息。

SELECT*

FROM学生

WHERE姓名Like“*龙*“;

例8.13:查询“学生”表中“学号”字段第4、5位是“23”的学生的“姓名”“性别”“出生日期”和“生源”信息。

SELECT学号,姓名,性别,出生日期,生源

FROM学生

WHERE学号Like“23*“;

(4)使用BETWEEN运算符

BETWEEN运算符为区间运算符,表示介于两个值之间。

其格式如下:

〈列名〉[NOT] BETWEEN〈值1〉AND〈值2〉

NOTBETWEEN是BETWEEN的否定运算。

例8.14:查询“学生”表中1997~1998年出生的学生的“姓名”“性别”“出生日期”和“生源”信息。

SELECT姓名,性别,出生日期,生源

FROM学生

WHERE出生日期Between#1/1/1997#And#12/31/1998#;

说明:日期前后要加上“#”;使用BETWEEN时应包括边界值,上述条件等价于

出生日期〉=#1/1/1997#And出生日期〈=#12/31/1998#。

(5)使用IN运算符

IN运算符是成员判断运算符,判断指定值是否在指定的值的集合中。

其格式如下:

〈列名〉[NOT] IN(〈值1〉, 〈值2〉,…, 〈值n〉)

NOTIN是IN的否定运算。

例8.15:查询“学生”表中所有“团员”和“党员”的学生信息。

SELECT*

FROM学生

WHERE政治面貌In(“党员“,“团员“);

(6)使用ISNULL

ISNULL是空值判断运算符,用于检查是否为NULL。 ISNOTNULL是ISNULL的否定运算。

例8.16:假设“成绩”表未考试科目的“成绩”字段值为NULL,查询已考试科目的课程号且课程号不重复。

SELECTDISTINCT课程号

FROM成绩

WHERE成绩Is Not Null;

说明:条件不可写成“列名=NULL”;NULL就是空,ISNULL或ISNOTNULL可用于任何类型的字段;空值表示未知值,不等同于“空字符串”和数值0。

3.统计查询

利用SQL 的统计函数对字段进行求和、平均值、最大值、最小值或计算相关运算,输出列为统计函数的返回值。SQL 的常用统计函数如表8-1所示。

表8-1SQL 的常用统计函数

例8.17:查询并统计“成绩”表中课程号为“101”的课程的最高分、最低分和平均分。

SELECTMax(成绩) AS最高分,Min(成绩) AS最低分,Avg(成绩) AS平均分

FROM成绩

WHERE课程号=“101“;

4.自然连接查询

自然连接是一种特殊的等值连接,要求两个关系表中进行比较的必须是相同的属性列,在结果中消除重复的属性列。

例8.18:查询成绩在60与80分之间(含60分与80分)的所有学生的“学号”“姓名”“课程号”及“成绩”。

SELECT学生.学号,姓名,课程号,成绩

FROM学生,成绩

WHERE学生.学号 =成绩.学号And成绩〉=60And成绩〈=80;

说明:学号字段同时存在“学生”表和“成绩”表中,在学号字段前必须加上表名作为前缀,以标识是哪一个表的学号;而其他几个字段是唯一的,故可省略各自的前缀。

5.分组查询

GROUPBY子句通常和聚集函数一起使用,用来对查询结果进行分组,目的是细化聚集函数的作用对象。 分组聚集函数作用于每个组。

例8.19:查询并统计“成绩”表中各门课程的最高分、最低分和平均分。

SELECT课程号,MAX(成绩) AS最高分,MIN(成绩) AS最低分,AVG(成绩) AS平均分

FROM成绩

GROUPBY课程号;

例8.20:查询并统计“教师”表中各职称的男女教师的人数。

SELECT职称,性别,Count(*) AS人数

FROM教师

GROUPBY职称,性别;

例8.21:查询并统计“教师”表中各职称的男教师的人数,仅要求输出人数大于等于5的信息。

SELECT职称,COUNT(*) AS人数

FROM教师

WHERE性别=“男“

GROUPBY职称HAVINGCOUNT(*)〉=5;

说明:SELECT子句中的列名表项,要么是统计函数,要么必须出现在GROUPBY子句中。 当有多个分组依据时,各分组依据之间用逗号隔开。 HAVING子句不同于WHERE子句,它是对分组结果进行筛选。 WHERE子句是指定哪些记录能够参与统计,而HAVING子句指定的是分组后作为查询结果输出的条件。

6.排序

在SELECT-SQL 语句中使用ORDERBY子句,可使查询结果按一定的顺序显示。

例8.22:查询“成绩”表中所有选修课程的学生的“学号”“课程号”和“成绩”信息,并按“学号”升序排列,“学号”相同的再按“成绩”降序排列。

SELECT学号,课程号,成绩

FROM成绩

ORDERBY学号,成绩DESC;

8.5.4SQL 数据更新语句

SQL 数据更新操作有三种:添加记录、修改记录和删除记录,分别由INSERT、UP-DATE和DELETE语句实现。

1.添加记录

格式:INSERTINTO〈表名〉[(〈列名1〉[,〈列名2〉[,)]]

VALUES(〈常量1〉[,〈常量2〉[,)];

功能:将新记录添加到指定〈表名〉中。 其中,新记录的〈列名1〉的值为〈常量1〉,〈列名2〉的值为〈常量2〉,以此类推。 INTO子句中没有出现的列,新记录在这些列(字段)上将取空值。 但必须注意:如果表定义时说明了NOTNULL的列不能取空值,则插入全部字段的值时,列名表可省略。

例8.23:将一个新学生的信息(学号为S16230102,姓名为李云,性别为女,出生日期为1998-5-7,生源为福建,政治面貌为团员,班级号为C201)

INSERTINTO学生

VALUES(“S16230102“,“李云“,“女“,#1998-5-7#,“福建“,“团员“,“C201“)

2.修改记录数据

格式:UPDATE〈表名〉

SET〈列名〉=〈表达式〉[,〈列名〉=〈表达式〉式,〈E〈)ERE〈条件表达式〉];

功能:修改指定〈表名〉中满足〈条件表达式〉的记录数据。 其中,SET子句中的〈表达式〉的值用于更新相应〈列名〉的字段值。 如果省略WHERE子句,则表示修改表中的所有记录数据。

例8.24:将“学生”表中“张琛”同学的政治面貌改为“党员”。

UPDATE学生

SET政治面貌 =“党员“

WHERE姓名=“张琛“;

3.删除记录数据

格式:DELETE

FROM〈表名〉

[WHERE〈条件表达式〉];

功能:删除指定〈表名〉中满足〈条件表达式〉的所有记录数据。 如果省略WHERE子句,则删除表中的所有记录,使指定表成为空表,但表的定义仍然存在。

例8.25:删除“成绩”表中成绩不及格的学生的记录。

DELETE

FROM成绩

WHERE成绩〈60;