聚合函数:
SQL提供了下列聚合函数:
COUNT(*) | 计算元组的个数 |
COUNT(<列名>) | 对一列中的值计算个数 |
SUM(<列名>) | 求某一列值的总和(此列的值必须是数值型) |
AVG(<列名>) | 求某一列的平均值(此列的值必须是数值型) |
MAX(<列名>) | 求某一列的最大值 |
MIN(<列名>) | 求某一列的最小值 |
SELECT语句的完整结构:
SELECT<目标表的列名或列表达序列>
FORM<基本表名 或/和 视图序列>
[ WHARE <行条件表达式>]
[ GROUP BY <列名序列>
[ HAVING <组条件表达式> ] ]
[ORDER BY <列名[ ASC | DESC ]>, ... ]
整个语句的执行过程如下:
- 读取FORM子句中的基本表、视图的数据,执行笛卡儿积操作;
- 选取满足WHERE子句中给出的条件表达式的元组;
- 按GROUP子句中指定列的值分组,同时提取满足HAVING子句中组条件表达式的那些列;
- 按SELECT子句中给出的列名或列表达式求值输出;
- ORDER子句对输出的目标表进行排序,ASC表示升序排列,DESC表示降序排列。
关于SELECT子句:
SELECT子句用于描述查询输出的表格结构。其形式如下:
SELECT [ ALL | DISTINCT ] <列名或列表达式序列> | *
- DISTINCT 选项保证重复的行将从结果中去除;ALL是默认值,表示重复的行留在结果中;
- 星号 * 表示选择所有列;
- 列表达式的意思是对一个单列求聚合值的表达式,即运用上面的聚合函数;
- 允许表达式中出现+,-,*,/以及列名、常数的算数表达式。
列和基本表的改名操作:
使用AS可以给列和基本表进行改名。有时一个基本表在多个SELECT中出现或用户要求输出的列名和基本表中的不一致,就可以给基本表或列改名。
SELECT SNAME AS STUDENT_NAME
FORM S AS STUDENT
集合的并、交、差操作:
当两个子查询的结构完全一致时,可以将这两个子查询进行并、交、差等操作。并、交、差的运算符是:UNION、INTERSECT、EXCEPT。三个关键字后面带上ALL,则不消除重复元组,不带ALL,则返回的结果消除重复元组。
(SELECT 查询语句1) UNION [ ALL ] (SELECT 查询语句2) |
(SELECT 查询语句1) INTERSECT [ ALL ] (SELECT 查询语句2) |
(SELECT 查询语句1) EXCEPT [ ALL ] (SELECT 查询语句2) |
上述操作不带关键字ALL, 返回结果中消除了重复元组;带ALL,不消除重复元组。
关于WHERE子句:
在WHERE子句中的条件表达式F中可以使用下列运算符:
- 算术比较运算符:<, <=, >, >=, =, <>或!=
- 逻辑运算符:AND, OR, NOT
- 集合成员资格运算符:IN, NOT IN
- 谓词:EXISTS, ALL, SOME, UNIQUE
- 聚合函数:AVG, MIN, MAX, SUM, COUNT
- 区间判断:[NOT] BETWEEN ... TO ...
- 等值判断:[NOT] LIKE
- 空值判断:IS [NOT] NULL
- F中的运算对象还可以是另一个SELECT语句,即SELECT可以嵌套。
字符串匹配操作:
字符串匹配操作符是“LIKE", 在表达式中可以使用两个通配符:
- 百分号:与零个或多个字符组成的字符串匹配;
- 下划线:与单个字符匹配。
//匹配S中以字母D打头的学生姓名SELECT SNAME
FORM S
WHERE SNAME LIKE'D%';
为了使字符串中包含特殊字符(%和_),SQL允许定义转义字符。转义字符紧靠特殊字符并放在前面,表示该特殊字符将被当作普通字符。在LIKE中使用ESCAPE关键字来定义转义字符。
LIKE 'ab\%cd%' ESCAPE'\' //匹配所有以ab%cd开头的字符串
SQL还允许在字符上使用多种函数,例如连接(”||“),提取子串,计算字符串长度,大小写转换等操作。
空值的比较操作:
SQL允许列值为空,空值用NULL表示,NULL不占用空间。
空值的存在增加了算术操作和比较操作的复杂性。SQL中规定,涉及+,-,*,/的算术表达式中有一个值是空值时,表达式的值也是空值。涉及空值的比较操作的结果认为是”false“。
在聚合函数中遇到空值时,除了COUNT(*)外,都跳过空值去处理非空值。
集合成员资格的比较:
判断元组是否在查询的结果(即集合)中的操作,叫做”集合成员资格的比较“。其形式为:
<元组> [NOT] IN (<集合>)
这里的元组和集合的形式应该相同。IN操作符表示,如果远足在集合内,则返回true。
//在S和SC中检索至少不学C2和C4两门课的学生学号SELECT S#
FORM SWHERE S# NOT IN (SELECT S#
FORM SC
WHERE C# IN ('C2','C4'));
集合成员算术的比较:
其形式如下:
<元组> θ ALL | SOME | ANY (<集合>)
θ是算术比较运算符”θ ALL"表示左边那个元组和右边集合中每一个元组满足θ运算;“θ SOME"和”θ ANY“意义一样,表示左边那个元组和右边集合中至少一个元组满足θ运算。
这里应该注意,元组的比较操作和字符串的比较操作类似。例如:
(a1, a2) = (b1, b2),其意义是(a1<b1) OR (a1=b1) AND (a2<=b2)
集合中重复元组是否存在测试:
SELECT T#, TNAME
FORM TWHERE UNIQUE (SELECT T#
FORM C
WHERE C.T# = T.T#);
嵌套查询的改进写法
导出表的使用
SQL语句允许在FORM中使用子查询。如果在FROM中使用了子查询,那么要为查询的结果起一个表名和相应的列名。
//在基本表SC中检索平均成绩最高的学生学号
SELECT SC.S#
FROM SC,(SELECT AVG(SCORE)
FROM SC
GROUP BY S#) AS RESULT(AVG_SCORE)
GROUP BY SC.S#
HAVING AVG(SC.SCORE)>=ALL(RESULT.AVG_SCORE);
WITH子句的临时视图
SQL允许用户用WITH语句定义一个临时视图(即子查询),置于SELECT语句的开始处。而临时视图本身是用SELECT语句定义的。
WITH RESULT(AVG_SCORE)AS
SELECT AVG(SCORE)
FROM SC
GROUP BY S#
SELECT S#
FROM SC.RESULT
GROUP BY S#
HAVING AVG(SCORE)>=ALL(RESULT.AVG_SCORE);