数据查询是数据库中最常用的操作。SQL提供select语句在一定条件下对指定的基本表进行查询。由于查询需求的复杂程度不同,可分为单表查询和多表查询。两种查询将在后面依次进行介绍。
在介绍单表查询和多表查询之前,首先我们提出select 语句查询基本格式为:
SELECT 属性列表
FROM 表名
[WHERE 条件表达式1]
[GROUP BY 属性名1 [HAVING 条件表达式2]]
[ORDER BY 属性名2 [ASC | DESC]]
为了更清楚的理解上面所提出关键字的具体含义,这里不做标准化的介绍。
- select 后是你想查询的属性名称;
- from 后是属性名称来自于那个基本表;
- where 后是根据你所需要查询的属性提供条件限制,以便得到正确的查询结果(这里是对基本表做出限制);
- group by 是将查询结果分组,分组的依据是其后的属性名称;
- having 是根据你所需要查询的属性提供条件限制,以便得到正确的查询结果(这里是对经过group by语句后得到的组进行限制);
- order by 是对所得查询结果按照一定的条件进行排序,排序的依据就是其后的属性名称,sql默认排序结果是升序(asc),如果想按照降序进行排序,在属性名称后声明desc即可;
备注:
- 执行完select查询语句后,所得的结果仍然是一张表;
- select语句执行的过程是
- 执行where语句按照条件在指定的基本表中进行选取操作,选取出合适的元组;
- 执行select语句对所得元组的集合进行投影操作;
- 如果没有其余的语句则说明查询结束,输出查询结果。如果由group by 或者 order by语句,则还需要进行相应的分组、排序操作,最终输出结果;
好了,有了以上了的认识之后我们首先来看看单表查询。对单表查询是比较简单的,主要分类有无条件查询、条件查询、分组查询、合并查询等。
我们在这里给出一个学生表S(学号,姓名,性别,年龄,专业),如图所示:
<1>无条件查询:
定义:所谓的无条件查询其实就是不包含where语句的查询,这种查询方式只包括“select...from”。是最简单的查询。
举例:
1、查询全体学生的学号、姓名、性别;
2、查询全体学生的基本信息;
“*”表示所有列名,通过这种方式我们可以查看整张基本表中的全部数据。
<2>条件查询:
定义:条件查询和无条件查询最大的区别就是加上了where语句,where语句通过比较运算符写出判断条件,并依照此条件进行执行。常见的比较运算符如下表所示:
运算符 | 含义 |
=、>、<、>、=<、=!、<> | 比较多小 |
AND、OR、NOT | 多重条件 |
BETWEEN AND | 确定范围 |
IN/NOT IN | 确定集合 |
LIKE/NOT LIKE | 字符匹配 |
IS NULL/IS NOT NULL | 空值 |
说明:
- NOT用于修饰BETWEEN AND、IN、LIKE、IS NOLL等;
- BETWEEN...AND...在mysql和SQL Server中包含边界值
- IN是对于集合的操作
- LIKE用于字符匹配,比较常用的有_和%。_表示一个字符,%代表多个字符。当记不清具体的属性值时,可以用LIKE找出相关的信息,然后进行下一步操作;
- IS NOT表示某个字段为空,某个字段不为空时IS NOT NULL,不能写成!= NULL,这是错误的。
- <>表示不等于,和 != 是一个意思,只不过出现的先后顺序不一样罢了。
举例:
1、查询学号为’s1‘学生的基本信息;
2、查询男性学生其专业是计算机专业的学生姓名;
3、查询年龄在18~20之间学生的信息;
4、查询非计算机专业学生的全部信息;
5、查询姓钱学生的专业;
6、查询有学号学生的全部信息;
<3>常用库函数及统计汇总查询:
函数名称 | 功能 |
AVG | 按列计算平均值 |
SUM | 按列计算值的总和 |
MAX | 求一列中的最大值 |
MIN | 求一列中的最小值 |
COUNT | 按列值统计个数 |
举例:
查询选择计算机专业学生的个数;
说明:as的作用为起别名;
<4>分组查询:
举例:
1、查询出专业学生人数等于2的专业名称;
以上就是介绍的关于单表查询的一些基本操作,接下来来介绍一下多表查询。
为了介绍多表查询,在已有学生表S的基础上,我们再增添几张表格,分别是:
教师表T(教师号,姓名,性别,年龄,职称,工资,岗位津贴,系别)
课程关系表C(课程号,课程名,课时)
选课关系表SC(学号,课程号,成绩)
授课关系表TC(教师号,课程号)
所谓的多表查讯其实就是为了满足更复杂的查询要求,查询的属性来自不同的表格,因此必须联系多个表组合起来得到最终的结果。常见的查询方式有内连接查询和外连接查询,交叉查询,自连接查询,子查询,而外连接又分为左连接和右连接,接下来我们将详细进行介绍。
<1>内连接和外连接:
1、所谓的内连接(INNER JOIN)其实就是将几张不同的基本表通过一定条件联系起来,根据希望输出的属性,输出满足限制条件的那部分内容,其基本格式为:
SELECT a.属性名1,a.属性名2,...,b,属性名1,b.属性名2... FROM table_name1 a, table_name2 b on a.id = b.id where a.属性名 满足某些条件;
1、外连接分为左连接和右连接
- JOIN左边的表叫做左表,右边的表叫做右表;
a、左连接(LEFT JOIN)其实就是根据希望输出的属性,不仅输出满足限制条件的那部分内容,左表中的不满足条件的数据会以NULL来显示,其基本格式为:
SELECT a.属性名列表, b.属性名列表 FROM table_name1 a [OUTER] LEFT JOIN table_name2 b on a.id = b.id;
b、右连接(RIGHT JOIN)其实就是根据希望输出的属性,不仅输出满足限制条件的那部分内容,右表中的不满足条件的数据会以NULL来显示,其基本格式为:
SELECT a.属性名列表, b.属性名列表 FROM table_name1 a [OUTER] RIGHT JOIN table_name2 b on a.id = b.id;
举例:
1、查询所有选课学生的学号、姓名、成绩;
通过内连接查询到满足限制条件的结果,由于学号为’s6‘的同学没有选课,所以未对其进行输出;
通过左连接查询,由于S表在JOIN的左边,所以S表为左表,这次不单单查询到满足限制条件的结果,同时对为满足条件的’s6‘同学进行输出,其数据为NULL;
右连接同理,这里不作具体分析。
<2>交叉查询:
通过观察分析上面的内连接查询和外连接查询对于表的连接具有一点的要求,那就是两个表必须拥有相同的属性才可以进行连接,而交叉查询对连接查询表没有特殊的要求,任何基本表之间都可以进行交叉查询;
举例:对学生表S和教师表T进行交叉查询;
由于输出结果过长,此处仅仅粘贴了一部分结果,可以看出查询的集合实际上两个表进行了笛卡尔积运算。
<3>自连接查询:
有时候我们查询一个结果的时候,通过和自身进行连接,最终得到正确的输出,和自己进行连接的查询方式为自连接查寻。
举例:
1、查询所有比’刘伟‘工资高的教师的教师姓名、工资、职称和刘伟的工资;
<4>子查询
关于子查询的分类,如图所示:
所谓的子查询其实就是在where子句后面嵌套上select...from...where语句,where子句中还可以接着嵌套,嵌套的称为父查询或外查询,被嵌套的称为子查询或内查询;
普通子查询执行顺序为依据最后一个select语句的执行结果来决定上一个select语句的输出结果,直到到第一个select语句;而相关子查询的执行顺序为先选取父查询表的第一行记录,然后其嵌套的子查询利用这个记录进行判断,如果满足条件,该行记录就放在输出集合中,直到父查询的最后一行记录被查询,此时的便得到最终结果。
where子句后面的select语句并不是可以无限嵌套的,其最多嵌套个数为25。
a、返回一个值:
举例:查询与’刘伟‘老师职称相同的教师号、姓名。
分析:这个语句首先执行内查询找出刘伟老师的职称,注意内查询返回的是一个值,然后将该值称赋给prof,此时外查询相当于select tno,tn fromt where prof = ’讲师‘。这是一个简单的单表查询。
b、返回一组值:
举例:
1、查询其他系中比计算机系某一教师工资高的教师的姓名和工资;
分析:首先执行的是内查询,其返回的是教师表中计算机系的老师的薪水集合,它包含一组值,题目中要求是比某一教师工资高的教师的信息,说明非计算机系的老师只要比集合中任意一个值大就可以说,换言之,找出计算机系老师的最低薪水,只要比这个值大就满足题目条件,故我们采用ANY,我们同样可以把ANY换成IN是一样的,其表示的意思是只要外查询的的值大于内查询的一个值就满足条件,这里对于IN不做i详细描述。
2、查询其他系中比计算机系所有教师工资高的教师的姓名和工资;
分析:首先执行的是内查询,其返回的是教师表中计算机系的老师的薪水集合,它包含一组值,题目中要求是比所有教师工资高的教师的信息,说明非计算机系的老师需要比集合中的全部值都要大才可以。换言之,找出计算机系老师最高薪水,非计算机系的老师薪水只要比这个值大就满足题目条件,故采用ALL。
c、相关子查询
举例:
1、查询不讲授课程号为 ‘c5’ 的教师姓名;
分析:首先选取父查询的第一行记录的教师号字段值,为't1',即 t.tno = 't1';依据此条件对内查询进行查询,得到的结果为’t1‘老师所教授的课程号集合,然后父查询判断’c5‘课程在不在集合中,如果没在,则符合题意,于是把改行放在父查询的结果集合中。重复上述过程,最终得到输出结果。
d、EXISTS相关子查询
EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False
EXISTS 指定一个子查询,检测 行 的存在。
举例:
1、查询不讲授课程号为 ‘c5’ 的教师姓名;
分析:首先选取父查询的第一行记录的教师号字段值,为't1',即 t.tno = 't1';在内查询的where子句要,找出有没有满足这个两个条件的行,如果不存在则说明NOT EXITES为TRUE,组说明符合题意,于是把改行放在父查询的结果集合中。重复上述过程,最终得到输出结果。
以上就是对多表查询的全部介绍。
关于单表查询和多表查询做出以下总结:
无论是单表查询还是多表查询均依赖于最基本的select...from...where语句,对于单表查询一个简单的select...from...where语句便可以完成查询要求,而对于多表查询,其实最关键的在于where后添加的条件判断,如果是简单的条件表达式,可以借助运算符完成,如果是复杂的条件表达式,可以借助ANY,ALL,EXISTS等与select...from...where语句结合完成条件表达式。同时对于函数的运用,也一定程度的简化了查询操作。
换句话说,select...from...where语句是一个毛坯房,如何使房子更加美观,达到自己内心的期望,则需要借助于各式各样的方法完成。