数据查询我们是分单表查询,连接查询,嵌套查询,集合查询以及了解Select语句的一般形式。
好了,首先说说单表查询,其分五个内容,为选择表中的若干列,选择表中的若干元组(重行与不重行的问题),ORDER BY子句,聚集函数,GROUP BY子句,前面两者比较简单,所以就简单的介绍一下,选择表中的若干列的话,你就得多留意一下列中可能有需要计算的列和改名字的内容,而选择表中的若干元组,你得明白重行与不重行的问题,以及清楚的知道常用的查询条件和查询条件的特殊,字符匹配的应用,多重条件查询(AND):
前两者就是那么简单,好了,现在我们开始说说ORDER BY子句了,
v ORDER BY子句
n 可以按一个或多个属性列排序
n 升序:ASC;降序:DESC;缺省值为升序
v 当排序列含空值时
n ASC:排序列为空值的元组最后显示
n DESC:排序列为空值的元组最先显示
例子:
[例24] 查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列。
SELECT Sno,Grade FROM SC WHERE Cno= ‘ 3 ‘ ORDER BY Grade DESC;
[例25] 查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列。
SELECT * FROM Student ORDER BY Sdept,Sage DESC;
然后进入到我们的聚焦函数(以记录为单位去处理的):
例子:
[例26] 查询学生总人数。
SELECT COUNT(*)
FROM Student;
[例27] 查询选修了课程的学生人数。
SELECT COUNT(DISTINCT Sno)
FROM SC;
[例28] 计算1号课程的学生平均成绩。
SELECT AVG(Grade)
FROM SC
WHERE Cno= ‘ 1 ‘;
最后进入到我们的GROUP BY子句
v GROUP BY子句分组:
细化聚集函数的作用对象
- 未对查询结果分组,聚集函数将作用于整个查询结果
- 对查询结果分组后,聚集函数将分别作用于每个组
- 作用对象是查询的中间结果表
- 按指定的一列或多列值分组,值相等的为一组
例子:
[练习] 求各个同学及相应的选课门数。
SELECT Sno,COUNT(Cno)
FROM SC
GROUP BY Sno;
注意点:
v HAVING短语与WHERE子句的区别:
- 作用对象不同
- WHERE子句作用于基表或视图,从中选择满足条件的元组,HAVING短语作用于组,从中选择满足条件的组
例子:
[例32] 查询选修了3门以上课程的学生学号。
SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(*) >3;
以上就是单表查询的所有内容,现在我们就要开始说说多表查询了,首先说说多表查询的第一个内容,就是连接查询, 连接查询的含义就是涉及到多个表的查询,而要想我们的表连接起来,必定需要有连接参数,所以必须会用到连接参数的条件,而常常我们连接表的时候需要条件的一般的格式:
因为我们特别注意的一点是连接条件中的各连接字段必须是可比的,但名字不必是相同的,而在执行我们的条件操作的时候(特指连表的条件,其他条件都是基于这个条件的操作进行的),有三种方法,
第一种为嵌套循坏法,其就是先从表一找到一个元祖,然后从头开始扫描表二,逐一查找满足联建条件的元组,找到后就将表1中的第一个元组与该元组拼连起来,形成结果表中的一个元组,表二全部查完之后,在找表1的第二个元组,然后的步骤跟上相似,直到把表1的全部元组都处理完毕。但是这个方法有一个很大的弊端就是无论怎样,他都要把表2的所有元组都要扫完后才进行表1的下一个元组的查询,这样子的效率就很慢,所以为了改善效率,于是提出了第二种方法和第三种方法
第二种为排序合并法,其常用于=连接的情况,其步骤是按连接属性对表1和表2排序,对表1的第一个元组,从头开始扫描表2,顺序查找满足连接条件的元组,找到后就将表1的第一个元组与该元组拼接起来,形成结果表中的一个元组。当遇到表2中第一条大于表1连接字段值的元组时,对表2的查询不再继续,然后找表1的第二条元组,重复上述步骤。
第三种为索引连接,其步骤为对表2按连接字段建立索引,然后对表1的每个元组,依次根据其连接字段值查询表2的索引,从中找到满足条件的元组,找到后就将表1只能够的第一个元组与该元组拼接起来,形成表中的一个元组,重复上述步骤。
基于上面的基础,我们分连接查询有四种:等值于非等值连接查询,自身连接,外连接,复合条件连接,等值与非等值连接查询很简单,这边就不说了,而自身连接是一个表与其自己进行连接,我们需要给表起别名进行区别,由于所有的属性名都是同名属性,因此必须使用别名前缀,而外连接跟普通连接不同,普通连接操作只输出满足连接条件的元组,而外连接操作以指定的表为连接主题,将主题表中不满足连接条件的元组一并输出(为null值),而复合条件连接就是在基于等值于非等值连接的时候再进行多个条件的判断的一种连接,简单的说就是这个连接的条件是多个的。
嵌套查询
首先我们说说什么叫做嵌套查询,而了解嵌套查询,又要先理解好查询块的概念:在一个SELECT-FROM-WHERE语句称为一个查询块。而将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询
注意:1)子查询是有限制的,什么限制呢?
- 不能使用ORDER BY子句
2) 有些嵌套查询可以用连接运算替代
而嵌套查询的意义是层层嵌套方式反映了 SQL语言的结构化
好了,说完嵌套查询的相关概念,首先我们先说说嵌套查询四种方式的一个通用基础,就是分清楚是相关查询还是不相关查询。
不相关查询就是子查询条件不依赖于父查询,
其工作的原理是:由里向外 逐层处理。即每个子查询在上一级查询处理之前求解,子查询的结果用于建立其父查询的查找条件。
相关查询就是子查询的查询条件依赖于父查询,
其工作原理是:
- 首先取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理内层查询,若WHERE子句返回值为真,则取此元组放入结果表
- 然后再取外层表的下一个元组
- 重复这一过程,直至外层表全部检查完为止
说完了四大嵌套查询的基础之后,我们就要开始学四大嵌套查询了,那四大,就是
一、带有IN谓词的子查询
二、 带有比较运算符的子查询
三、 带有ANY(SOME)或ALL谓词的子查询
四、 带有EXISTS谓词的子查询
首先我们先说说——带有IN谓词的子查询
例子:
[例39] 查询与“刘晨”在同一个系学习的学生。
SELECT Sno,Sname,Sdept
FROM Student
WHERE Sdept IN
(SELECT Sdept
FROM Student
WHERE Sname= ‘ 刘晨 ’);
此查询为不相关子查询为基础的嵌套查询。
总结:in代表着如果其左边的列等于右边的任何一个数,其都可以返回一个记录
然后说说带有比较运算符的子查询
当我们知道子查询确切的返回单值的时候,可用比较符去比较,这就是带有比较运算符的子查询,其常和ANY或ALL谓词配合使用。而且特别注意一点,子查询一定要跟在比较符之后。
之后我们就要说说跟比较符一起使用的,带有ANY(SOME)或ALL谓词的子查询
其的谓语词义是ANY:任意一个值,ALL:所有值。其具体语法如下:
例子:
最后我们就说说带有EXISTS谓词的子查询,其是四大嵌套查询的难点,首先我们说说exist和not exist的作用,exist的作用就是如果子查询中有记录满足条件的,那么这条记录就会被返回,而not exist的作用是,如果子查询的某个记录不符合条件,那么其就会被返回。
直接看例子:
上面说的都是常规的exist的查询语句,我们还有一些特殊的使用exist的方法,比如下面的,
- 用EXISTS/NOT EXISTS实现全称量词(难点)
因为我们sql语句没有全程量词"(For all),所以我们可以把带有全称量词的谓语转换成等价的带有存在量词的谓语, ("x)P ≡ ? ($ x(? P))
例子:
选择不存在任何一门课程没有选择的人
- 用EXISTS/NOT EXISTS实现逻辑蕴函(难点),因为sql语言中没有蕴含逻辑运算,所以我们可以利用谓语演算将逻辑蕴含谓词等价转换为
p ? q ≡ ? p∨q
例子:
说完了嵌套查询,下面就说说最后一个多表查询的模块,就是集合查询,其是多条件查询的另外一种表示,集合查询的种类有:
- 并操作UNION
- 交操作INTERSECT
- 差操作EXCEPT
因为其是多条件查询的另外一种表示,所以参加集合操作的各查询结果的列数必须是相同的,对应项的数据类型也必须相同
下面我们看看例子:
最后我们进入到总结环节,首先总结一下select语句的一般格式:
最后是有关多表查询的总结:
1) 首先先明白我们要查的数据所涉及的因素,从而得出要想把这些因素都涉及起来需要用到那些表
2) 想清楚之后,我们就要开始想我们要用哪一种查询方式去查(根据各查询方式的题目特点去判断)得到我们要的数据
注意:我们都需要明白,有关嵌套查询的,都需要明白我们在嵌套的时候是不相关查询还是相关查询,弄清楚之后在进行四种嵌套查询的语句。