一、单表查询
1.使用select子句选择表中若干列(选择);
2.使用where子句选择表中若干元组(投影);
3.使用where及between/not between确定属性值范围;
4.使用LIKE+通配符%以及_+转义短语ESCAPE进行字符匹配(大小写敏感);
5.使用谓词in/not in确定集合成员(也可以用OR实现);
6.使用ORDER BY+ASC/DESC对查询结果进行排序;
7.使用聚集函数进行数据描述性统计工作;
可以使用DISTINCT/ALL来确当是否去重;
同时注意是否对查询结果进行分组:
需要同时注意分组属性以及聚集属性
分组方法:
使用GROUP BY子句分组,按指定的一列或者多列值分组,值相等的为一组;
使用GROUP BY子句后,SELECT子句的列名列表中只能出现分组属性和聚集函数(实际上就是分组聚集后产生的新的关系模式);
GROUP BY子句的作用对象是查询的中间结果表;
使用HAVING短语筛选出最终输出结果,只有满足HAVING短语指定条件的组才被最终输出。
(HAVING短语与WHERE子句的区别:作用对象不同;WHERE子句作用于基表或视图,从中选择满足条件的元组;HAVING短语作用于分组,从中选择满足条件的分组)
本题有点特别的是:没有指定聚集属性,即便如此还是使用了聚集函数count。那么这样分组聚集做出来的临时表是什么样的呢?
——先根据Sno分组,临时表中只有分组属性这一个属性。count还是直接数元组数量。
L12有个有意思的点:可能有课程并没有90分以上的学生,但上图的做法并不会输出Cno,0.此时我们就需要用到广义投影+UNION把丢失的补回来。
二、连接查询
同时涉及多个表的查询称为连接查询。
常用格式:
连接条件中的各个连接属性类型必须是可比的,但不必是相同的。
连接查询的主要类型:
1.广义笛卡尔积:
SELECT * FROM R,S;(指关系的笛卡尔积)
2.θ-连接(含等值连接)
在多个关系的笛卡尔积上使用连接条件产生结果。
3.自然连接
在等值连接中去掉把目标列中重复的属性。
要么自己指定属性集,要么在FROM子句中使用NATURAL JOIN关键字。
自然连接会匹配两个关系中所有同名属性上对应相等的元组,但是属性虽然同名,含义却可能不同,此时我们将使用JOIN USING关键字进行部分同名属性的“自然连接”。
4.自连接查询(self-join)
一个表与它自己进行连接。
需要给表起别名以示区别,由于所有属性名都是同名属性,因此必须使用别名前缀。
5.外连接查询
左外连接:取出左侧关系中与右侧任一元组都不匹配(根据自己指定的连接条件判断)的元组,用null填补来自右侧关系的属性加入结果。
全外连接为左∪右。
注意JOIN USING关键字代表的是自然连接。
( FROM R1,R2,……,Rn是广义笛卡尔积。)
使用θ-join或笛卡尔积都能比较方便地做关系的连接。
3.嵌套查询
一个SELECT-FROM-WHERE语句称为一个查询块,将一个查询块嵌套在另一个查询块的WHERE 子句或HAVING短语的条件中的查询称为嵌套查询。
嵌套查询一般的求解方法:由里向外处理, 每个子查询在上一级查询处理之前求解,子查询的结果用于建立其父查询的条件。
对子查询的限制:不建议或无法使用ORDER BY子句。
有一些嵌套查询可以用连接替代。嵌套本身就是为了准备数据嘛。
嵌套查询分类及求解方法:
不相关子查询:
子查询的查询条件不依赖于父查询。由里向外逐层处理,每个子查询在上一级查询处理之前求解,子查询的结果用于建立其父查询的查找条件。
相关子查询:
子查询的查询条件依赖于父查询。
求解:首先取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理内层查询,若WHERE子句返回值为真,则取此元组放入结果表;再处理外层表的下一个元组,直到外层表检查完。
L24为不相关子查询。这种嵌套嘛感觉比笛卡尔积更直观?
内层查询要依赖外层查询的属性值S.sno,为相关子查询。
常见子查询:
1.带有IN谓词的子查询
准备数据阶段使用嵌套。
查客体,找联系,通过联系查主体。
2.带有比较运算符的子查询
注意:必须确切知道内层查询返回单值才能使用;ANY谓词与SOME是一个意思,与ALL相对。
3.带有ANY或ALL谓词的子查询
4.带有EXISTS谓词的子查询
带有EXISTS(NOT EXISTS)谓词的子查询不返回任何数据,只产生逻辑值(True或False);若内层查询结果非空(为空),则外层的 WHERE子句返回真(假)值。
只能使用NOT EXIST如果使用双EXIST的话找到的是和20125122所选修的课程部分重合的人。
本例很重要:
其实和上面那种方法是一个思路,都是依靠双重否定。但是ppt上的更简洁也更复杂。
想要查询“在哈尔滨所有银行都有账户的客户”->查询对于任取的一个客户和一个银行:不存在这样的银行:这个银行没有这个客户的账号。
5.FROM子句中的子查询
子查询返回的结果用做查询目标关系。
6.带有WITH子句的子查询
定义临时关系(数据准备,用于嵌套查询)
下附一张ppt,是老师讲使用WITH子句、广义投影以及UNOIN操作解决的一道题。
7.标量子查询
返回单个属性的单个元组,其为可用于代替单值的表达式,使用在SELECT、WHERE和HAVING子句中。
4.集合查询
并UNION、交INTERSECT、差EXCEPT
注意:参加集合操作的各结果表必须是相容的,即列数相同,对应的数据类型相同。系统在并交差操作之前会自动去掉输入中的重复行。(去重时间往往大于查询时间)
SQL语言数据修改机制
数据插入:
在执行插入操作之前都应该判断是否破坏完整性约束。
数据更新
三种数据更新方式:
修改某一个元组的值;修改多个元组的值;带子查询的修改语句。
这个所有年龄增加一岁的写法就很有计算机的风格(
上图中左边这个写法是相关子查询,右边则是不相关的子查询。
更新被参照表,DBMS可能会拒绝这个请求;也有可能是级联更新,将参照表一起更新。
参照表中的外键属性不让更新。
数据删除
用’CS‘=……还能写一种。
SQL语言视图定义机制
视图是虚表,本身不保存数据,数据仍保存在基本表中。
视图更新:
并不是所有视图都能被更新,就比如使用聚集函数AVG定义的函数:
回溯不回基表上的视图肯定是不会允许更新的。
删除视图
CASCADE 瀑布流;级联。