数据查询语言DQL

聚合函数:

SQL提供了下列聚合函数:

COUNT(*) 计算元组的个数
COUNT(<列名>) 对一列中的值计算个数
SUM(<列名>) 求某一列值的总和(此列的值必须是数值型)
AVG(<列名>) 求某一列的平均值(此列的值必须是数值型)
MAX(<列名>) 求某一列的最大值
MIN(<列名>) 求某一列的最小值

SELECT语句的完整结构:

SELECT<目标表的列名或列表达序列>

    FORM<基本表名 或/和 视图序列>

    [ WHARE <行条件表达式>]

    [ GROUP BY <列名序列>

            [ HAVING <组条件表达式> ] ]

    [ORDER BY <列名[ ASC | DESC ]>, ... ]

整个语句的执行过程如下:

  1. 读取FORM子句中的基本表、视图的数据,执行笛卡儿积操作;
  2. 选取满足WHERE子句中给出的条件表达式的元组;
  3. 按GROUP子句中指定列的值分组,同时提取满足HAVING子句中组条件表达式的那些列;
  4. 按SELECT子句中给出的列名或列表达式求值输出;
  5. 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);

猜你喜欢

转载自my.oschina.net/HuoQibin/blog/1784656