数据查询

目录

格式

SELECT [ALL|DISTINCT] <目标列表达式>[,<目标列表达式>] …
FROM <表名或视图名>[, <表名或视图名> ] …
[ WHERE <条件表达式> ]
[ GROUP BY <列名1> [ HAVING <条件表达式> ] ]
[ ORDER BY <列名2> [ ASC|DESC ] ];
  • SELECT子句:指定要显示的属性列

  • FROM子句:指定查询对象(基本表或视图)

  • WHERE子句:指定查询条件

  • GROUP BY子句:对查询结果按指定列的值分组,该属性列值相等的元组为一个组。通常会在每组中作用聚集函数。

  • HAVING短语:只有满足指定条件的组才予以输出

  • ORDER BY子句:对查询结果表按指定列值的升序或降序排序

目录

  • 3.4.1 单表查询

  • 3.4.2 连接查询

  • 3.4.3 嵌套查询

  • 3.4.4 集合查询

  • 3.4.5 基于派生表的查询

  • 3.4.6 Select语句的一般形式

3.4.1单表查询

1.1选择表中的若干列

查询若干列

选出所有属性列:

  • 在SELECT关键字后面列出所有列名

  • 将<目标列表达式>指定为 *

查询经过计算的值

SELECT子句的<目标列表达式>可以为:

  • 算术表达式

  • 字符串常量

  • 函数

  • 列别名

1.2 选择表中的若干元组

消除取值重复的行,如果没有指定DISTINCT关键词,则缺省为ALL

指定DISTINCT关键词,去掉表中重复的行

查询满足条件的元组

常用的查询条件

多重查询:

  • 逻辑运算符:AND和 OR来联结多个查询条件

    • AND的优先级高于OR

    • 可以用括号改变优先级

  • 可用来实现多种其他谓词

    • [NOT] IN [NOT]

    • BETWEEN … AND …

1.3 ORDER BY子句

  • ORDER BY子句

    • 可以按一个或多个属性列排序

    • 升序:ASC;降序:DESC;缺省值为升序

  • 当排序列含空值时

    • ASC:排序列为空值的元组最后显示

    • DESC:排序列为空值的元组最先显示

1.4 聚集函数

聚集函数

  • 计数

    • COUNT([DISTINCT|ALL] *)

    • COUNT([DISTINCT|ALL] <列名>)

  • 计算总和

    • SUM([DISTINCT|ALL] <列名>)

  • 计算平均值

    • AVG([DISTINCT|ALL] <列名>)

  • 最大最小值

    • MAX([DISTINCT|ALL] <列名>)

    • MIN([DISTINCT|ALL] <列名>)

1.5 GROUP BY子句

GROUP BY子句分组:

细化聚集函数的作用对象

  • 未对查询结果分组,聚集函数将作用于整个查询结果

  • 对查询结果分组后,聚集函数将分别作用于每个组

  • 作用对象是查询的中间结果表

  • 分组方法:按指定的一列或多列值分组,值相等的为一组

HAVING短语与WHERE子句的区别: 作用对象不同

  • WHERE子句作用于基表或视图,从中选择满足条件的元组

  • HAVING短语作用于组,从中选择满足条件的组。

连接查询

连接查询:同时涉及多个表的查询

连接条件或连接谓词:用来连接两个表的条件

一般格式:

  • [<表名1>.]<列名1> <比较运算符> [<表名2>.]<列名2>

  • [<表名1>.]<列名1> BETWEEN [<表名2>.]<列名2> AND [<表名2>.]<列名3>v

连接字段:连接谓词中的列名称

连接条件中的各连接字段类型必须是可比的,但名字不必是相同的

连接操作的执行过程

嵌套循环法(NESTED-LOOP)

  1. 首先在表1中找到第一个元组,然后从头开始扫描表2,逐一查找满足连接件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组。

  2. 表2全部查找完后,再找表1中第二个元组,然后再从头开始扫描表2,逐一查找满足连接条件的元组,找到后就将表1中的第二个元组与该元组拼接起来,形成结果表中一个元组。

  3. 重复上述操作,直到表1中的全部元组都处理完毕

排序合并法(SORT-MERGE)

常用于=连接

  1. 首先按连接属性对表1和表2排序

  2. 对表1的第一个元组,从头开始扫描表2,顺序查找满足连接条件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组。当遇到表2中第一条大于表1连接字段值的元组时,对表2的查询不再继续

索引连接(INDEX-JOIN)

  1. 对表2按连接字段建立索引

  2. 对表1中的每个元组,依次根据其连接字段值查询表2的索引,从中找到满足条件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组

1.等值与非等值连接查询

等值连接

连接运算符为=

自然连接

同时完成选择和连接查询

一条SQL语句可以同时完成选择和连接查询,这时WHERE子句是由连接谓词选择谓词组成的复合条件。

执行过程:

  • 先从SC中挑选出Cno='2'并且Grade>90的元组形成一个中间关系

  • 再和Student中满足连接条件的元组进行连接得到最终的结果关系

2.自身连接

自身连接:

一个表与其自己进行连接

需要给表起别名以示区别

由于所有属性名都是同名属性,因此必须使用别名前缀

3.外连接

外连接与普通连接的区别

  • 普通连接操作只输出满足连接条件的元组

  • 外连接操作以指定表为连接主体,将主体表中不满足连接条件的元组一并输出

左外连接

  • 列出左边关系(如本例Student)中所有的元组

右外连接

  • 列出右边关系中所有的元组

查询结果:

4.多表连接

嵌套查询

嵌套查询概述

  • 一个SELECT-FROM-WHERE语句称为一个查询块

  • 将一个查询块嵌套在另一个查询块的WHERE子句 或HAVING短语的条件中 的查询称为嵌套查询

  • 子查询的限制:不能使用ORDER BY子句

  • 层层嵌套方式反映了 SQL语言的结构化

  • 有些嵌套查询可以用连接运算替代

不相关子查询:

子查询的查询条件不依赖于父查询

由里向外 逐层处理。即每个子查询在上一级查询处理之前求解子查询的结果用于建立其父查询的查找条件。

相关子查询

子查询的查询条件依赖于父查询

  • 首先取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理内层查询,若WHERE子句返回值为真,则取此元组放入结果表

  • 然后再取外层表的下一个元组

  • 重复这一过程,直至外层表全部检查完为止

1.带有IN谓词的子查询

2. 带有比较运算符的子查询

  • 当能确切知道内层查询返回单值时,可用比较运算符(>,<,=,>=,<=,!=或< >)。

  • 与ANY或ALL谓词配合使用

  • 假设一个学生只可能在一个系学习,并且必须属于一个系,则可以用 = 代替IN

  • 子查询一定要跟在比较符之后

可能的执行过程:

1) 从外层查询中取出SC的一个元组x,将元组x的Sno值(200215121)传送给内层查询。

SELECT AVG(Grade)

FROM SC y

WHERE y.Sno='200215121';

2) 执行内层查询,得到值88(近似值),用该值代替内层查询,得到外层查询:

SELECT Sno, Cno

FROM SC x WHERE Grade >=88;

3) 执行这个查询,得到

(200215121,1)

(200215121,3)

4)外层查询取出下一个元组重复做上述1至3步骤,直到外层的SC元组全部处理完毕。结果为:

(200215121,1)

(200215121,3)

(200215122,2)

3. 带有ANY(SOME)或ALL谓词的子查询

谓词语义

  • ANY:任意一个值

  • ALL:所有值

需要配合使用比较运算符

  • > ANY 大于子查询结果中的某个值

  • > ALL 大于子查询结果中的所有值

  • < ANY 小于子查询结果中的某个值

  • < ALL 小于子查询结果中的所有值

  • >= ANY 大于等于子查询结果中的某个值

  • >= ALL 大于等于子查询结果中的所有值

  • <= ANY 小于等于子查询结果中的某个值

  • <= ALL 小于等于子查询结果中的所有值

  • = ANY 等于子查询结果中的某个值

  • =ALL 等于子查询结果中的所有值(通常没有实际意义)

  • !=(或<>)ANY 不等于子查询结果中的某个值

  • !=(或<>)ALL 不等于子查询结果中的任何一个值

执行过程:

1)RDBMS执行此查询时,首先处理子查询,找出

CS系中所有学生的年龄,构成一个集合(20,19)

2) 处理父查询,找所有不是CS系且年龄小于

20 或 19的学生

用聚簇函数实现

4. 带有EXISTS谓词的子查询

  1. EXISTS谓词

    1. 存在量词

    2. 带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。

      1. 若内层查询结果非空,则外层的WHERE子句返回真值

      2. 若内层查询结果为空,则外层的WHERE子句返回假值

    3. 由EXISTS引出的子查询,其目标列表达式通常都用* ,因为带EXISTS的子查询只返回真值或假值,给出列名无实际意义

  2. NOT EXISTS谓词

    若内层查询结果非空,则外层的WHERE子句返回假值

    若内层查询结果为空,则外层的WHERE子句返回真值

逻辑表达式表达。。。待续

集合查询

集合操作的种类

  • 并操作UNION

    • UNION:将多个查询结果合并起来时,系统自动去掉重复元组。

    • UNION ALL:将多个查询结果合并起来时,保留重复元组

  • 交操作INTERSECT

  • 差操作EXCEPT

参加集合操作的各查询结果的列数必须相同;对应项的数据类型也必须相同

基于派生表的查询

子查询不仅可以出现在WHERE子句中,还可以出现在FROM子句中,这时子查询生成的临时派生表(Derived Table)成为主查询的查询对象

有聚集函数需要指定列名

如果子查询中没有聚集函数,派生表可以不指定属性列,子查询SELECT子句后面的列名为其缺省属性。

SELECT语句的一般格式

目标列表达式格式

(1) *

(2) <表名>.*

(3) COUNT([DISTINCT|ALL]* )

(4) [<表名>.]<属性列名表达式>[,<表名>.]<属性列名表达式>]…

其中<属性列名表达式>可以是由属性列、作用于属性列的聚集函数和常量的任意算术运算(+,-,*,/)组成的运算公式

聚集函数的一般格式

WHERE子句的条件表达式的可选格式

Last updated

Was this helpful?