先看一个自考题中最简单的例子:
有两个关系模式:职工(职工号,姓名,性别,年龄,职务,工资,部门号)
部门(部门号,部门名称,经理名,地址,电话)
试用SQL语句检索后勤部的所有人的姓名。
SELECT 姓名
FROM 职工,部门
WHERE职工.部门号=部门.部门号AND 部门.部门名称=’后勤部’
分析:如题对于基本表进行多表连接操作的时候,通过使用在WHERE子句中创建的“同等连接‘职工.部门号=部门.部门号’”从而将两张表关联起来,这是最简单的多表间的查询。用户进行基本连接操作时,SELECT子句列表中最好加上基表名称,FROM子句应包含所有使用的基表,WHERE子句中应定义一个同等连接。
通过上面的例子,引出这篇博客的主题————SELECT语句的多表查询。
多表查询中目前我们这个阶段使用最为广泛的是“子查询”,其实这几种查询在《数据库原理》中都有涉及,只是在归类方面比较乱,通过本篇博客,理清多表查询的结构、种类、区别等常见问题。
内(INNER JOIN)、外(OUTER JOIN)、交叉(CROSS JOIN)、自(INNER或OUTER JOIN)连接的结构可以统一写成:
SELECT select_list
FROM table1 join_type table2 [ON join_conditions]
[WHERE search_conditions]
[ORDER BY order_expression]
内连接有返回信息的条件是当且仅当至少有一个同属于两个表的行符合连接条件。内连接从第一标中消除与另个表中任何不匹配的行。
需注意外连接的两个表是有主从之分,以主表的数据去匹配从表中的数据,如果符合连接条件则返回到查询结果中,如果未从从表中找到匹配的行,主表的行依然保留并返回到查询结果中,相应的从表中的行被填上空值后返回到查询结果中。由此将外连接分为左外连接、右外连接、完全连接,就是根据主从表而划分的连接方式。
交叉连接可分为使用WHERE子句和不使用WHERE子句,后者返回直接在基表间进行笛卡尔积产生的结果,前者是返回直接标间进行笛卡尔积的结果减去WHERE子句条件搜索到的数据的行数。理解起来非常简单。
自连接指表与自身相连接的查询(给表定义别名)。例如:对机房收费系统中student_Info 表进行自连接查询,连接时通过内连接的方式来返回性别为“男”的“学号”“卡号”“姓名”
即:SELECT A.学号, A.姓名, B.学号,B.姓名
FROM student_Info A INNER JOIN student_Info B
ON A.卡号=B.卡号
WHERE A.性别=“男”
(关于JOIN连接和UNION连接,我认为只做了解就ok,使用时用简单连接就好了)
下面总结下子查询的使用。分类:1、返回单指子查询 2、返回多行子查询 3、嵌套子查询。
我理解的返回单值的子查询和返回多值的子查询区别在于子查询语句得出的元组的个数是否唯一,唯一则为单值的子查询,不唯一为多值的子查询,比如:
1、SELECT 员工编号,员工姓名,所在部门编号 FROM 员工信息
WHERE 所在部门编号 IN(SELECT 部门编号FROM 部门信息)
2、SELECT 员工编号,员工姓名,性别 FROM 员工信息
WHERE 所在部门编号 IN (SELECT 部门编号FROM 部门信息 WHERE 部门编号=‘技术部’)
用上边的两条查询语句就能够区别单值和多值子查询,关键就是IN的子句。
关于嵌套的子查询,就不多说了,自考书中有好多的例子。
最后想简单的总结一下联合查询。联合查询使用UNION关键字连接各个SELECT子句,将两个或者更多的查询结果组合为单个结果集,该结果集包含所有查询结果集中的全部行数据。基本格式如下:
SELECT select_list
FROM table_source
[WHERE search_conditions]
{UNION [ALL]}
SELECT select_list
FROM table_source
[WHERE search_conditions]
[ORDER BY order_expression]
其中ALL关键字可选,选中后返回全部满足匹配的结果;不使用该关键字,则在返回结果中删除满足匹配的重复行。在进行联合查询的时候,查询结果的列标题为第一个查询语句的列标题,因此,必须在第一个查询语句中定义列标题。同时如果对查询结果排序,则必须使用第一个查询语句中的列名、列标题和列序号。
我认为联合查询最需要注意的还是保证每个联合查询语句的选择列表中具有相同数量的表达式,且每个查询选择表达式应该具有相同的数据类型,这才是实现联合查询的关键所在。
举例:在【工资管理系统】数据库中的【员工信息】表中查询【所任职位】为“经理”的【员工编号】和【员工姓名】信息,并为其增加新列“当前位置”,列的内容为“员工信息表”;从【部门信息】表中查询所有【部门编号】和【部门名称】信息,并定义新增列的内容为“部门信息表”;最后将两个查询结果联合在一起。
如果使用联合查询,代码如下:
USE 工资管理系统
SELECT 员工编号,员工姓名,‘员工信息表’ AS 当前位置
FROM 员工信息
WHERE 所任职位=’经理’
UNION
SELECT 部门编号,部门名称,’部门信息表’
FROM 部门信息
分析:第一个查询语句中将“员工信息表”数据填入新增的【当前位置】列,第二个查询语句将“部门信息表”数据填入【当前位置】列中。两个查询语句中具有相同数量的表达式,数据类型相同,最终得到的结果便会组合在一张表中例如
员工编号 |
员工姓名 |
当前位置 |
00001 |
张振华 |
员工信息表 |
00002 |
王振华 |
员工信息表 |
10013 |
销售部 |
部门信息表 |
10014 |
后勤部 |
部门信息表 |
10015 |
财务部 |
部门信息表 |
当然用简单的SELECT语句也能实现上表中的效果,但是语句过于复杂,不过对于多表查询现阶段仅仅做了解就可以了,能够会用简单的多表查询就OK,等到以后需要深造的时候就会有点基础,那样学习起来路就会越走越顺了。