数据库原理及应用_数据库基础_第2章关系数据库标准语言SQL_数据查询(3)连接查询
前言
"<数据库原理及应用>(MySQL版)".以下称为"本书"中2.3.3节
引入
本书P54原话:连接查询是指对两个或两个以上的表或视图的查询.连接查询是关系数据库中最主要、最有实际意义的查询,是关系数据库的一项核心功能.
---从两张以上的表中查询到内容,才是用得最多的.
学习准备
建立表
参照本书P48和P49,建立三张表emp(雇员表),dept(部门表),salgrade(薪水等级表).如下
emp表
empno | ename | job | mgr | hiredate | sal | comm | deptno |
7369 | SMITH | CLERK | 7902 | 17/12/1980 | 800 | 20 | |
7499 | ALLEN | SALESMAN | 7698 | 20/2/1981 | 1600 | 300 | 30 |
7521 | WARD | SALESMAN | 7698 | 22/2/1981 | 1250 | 500 | 30 |
7566 | JONES | MANAGER | 7839 | 2/4/1981 | 2975 | 20 | |
7654 | MARTIN | SALESMAN | 7698 | 28/9/1981 | 1250 | 1400 | 30 |
7698 | BLAKE | MANAGER | 7839 | 1/5/1981 | 2850 | 30 | |
7782 | CLARK | MANAGER | 7839 | 9/6/1981 | 2450 | 10 | |
7788 | SCOTT | ANALYST | 7566 | 19/4/1987 | 3000 | 20 | |
7839 | KING | PRESIDENT | 17/11/1981 | 5000 | 10 | ||
7844 | TURNER | SALESMAN | 7698 | 8/9/1981 | 1500 | 30 | |
7876 | ADAMS | CLERK | 7788 | 23/5/1987 | 1100 | 20 | |
7900 | JAMES | CLERK | 7698 | 3/12/1981 | 950 | 30 | |
7902 | FORD | ANALYST | 7566 | 3/12/1981 | 3000 | 20 | |
7934 | MILLER | CLERK | 7782 | 23/1/1982 | 1300 | 10 |
dept表
deptno | dname | loc |
10 | ACCOUNTING | NEW YORK |
20 | RESEARCH | DALLAS |
30 | SALES | CHICAGO |
40 | OPERATIONS | BOSTON |
salgrade表
grade | losal | hisal |
1 | 700 | 1200 |
2 | 1201 | 1400 |
3 | 1401 | 2000 |
4 | 2001 | 3000 |
5 | 3001 | 9999 |
观察发现emp(雇员表)和dept(部门表)存在联系,两者都有一列叫做deptno(部门号)
笛卡尔积
连接查询的基本形态是笛卡尔积,理解成两张表相乘得到的结果是第一张表的一个元组与另一张表的每一个元组相乘,得到一张新的表.输入以下查询语句
SELECT deptno,dname,grade FROM dept,salgrade
ORDER BY deptno;
得到的结果是
deptno | dname | grade |
10 | ACCOUNTING | 1 |
10 | ACCOUNTING | 2 |
10 | ACCOUNTING | 3 |
10 | ACCOUNTING | 4 |
10 | ACCOUNTING | 5 |
20 | RESEARCH | 1 |
20 | RESEARCH | 2 |
20 | RESEARCH | 3 |
20 | RESEARCH | 4 |
20 | RESEARCH | 5 |
30 | SALES | 1 |
30 | SALES | 2 |
30 | SALES | 3 |
30 | SALES | 4 |
30 | SALES | 5 |
40 | OPERATIONS | 1 |
40 | OPERATIONS | 2 |
40 | OPERATIONS | 3 |
40 | OPERATIONS | 4 |
40 | OPERATIONS | 5 |
可以看出即使两张表毫无联系,也可以连接查询.对连接查询的结果有个印象(虽然结果也无意义)
笛卡尔积在连接查询中有着重要的地位,所有的连接查询都是以笛卡尔积为基础,一定要理解.
初探连接查询
连接查询是多表查询,和单表查询对比,FROM后面出现多个表的名称.
为查询方便,可以为表起别名;当对一张表查询两次时,必须起别名.
当两张表中有相同名称的列名(属性)时,冠以表名分开(可以使用表的别名)
连接查询要有实在意义,避免无意义的连接查询(如上例),如果要描述上例中的查询,他表达的是:"查询每个部门每个职位的薪水等级",在无其他条件限制的情况下,没具体意义.
抽象理解
两张表有相同的属性值(属性1-1),以此为依据找到其他属性的对应关系,
表1 | 表2 | 新表(表1连接表2) | ||||||
属性1-1 | 属性1-2 | 属性1-1 | 属性2-2 | 属性1-1 | 属性1-2 | 属性2-2 | ||
值1 | 值2 | 值1 | 值3 | 值1 | 值2 | 值3 |
1.相等连接
概念:又称为简单连接或内连接,它是把两个表中指定列的值相等的行连接起来.
格式1:
SELECT 列名1,....列名n FROM 表1,表2
WHERE 条件表达式1,...条件表达式n
格式2:
SELECT 列名1,....列名n FROM 表1 INNER JOIN 表2 ON
WHERE 条件表达式1,...条件表达式n
推荐格式2---表1 INNER JOIN 表2 ON ,原因很简单,一眼就看出是连接查询
含义:如"抽象理解"那张图所示---两张表中由相同属性值查找出不同属性间的关系.
本书P55例2-27,要求:查找薪资≥3000的人的讯息(雇员编号,雇员名,薪水,部门编号)---来自emp表及所在位置loc---来自dept表
输入查询语句
SELECT empno,ename,sal,e.deptno,loc FROM emp e INNER JOIN dept d
ON e.deptno=d.deptno
WHERE sal>=3000
ORDER BY e.deptno;
运行结果
2.自身连接
概念:通过把一个表定义成两个不同别名的方法(即把一个表映射成两个表)来完成自身连接
格式:
SELECT 别名1.列名 别名, 别名2.列名 别名
FROM 表1 别名1,表1 别名2
WHERE 条件表达式1,...条件表达式n
格式写法上和相等连接的格式1类似,格式有点难记,看后面的例子
应用场景:
自身连接的应用场景有点特殊,一张表中的两列存在相等的联系.如本书的emp表,有一列员工编号empno,一列管理员编号mgr.管理员同时也是员工.此时可以查询雇员对应的管理员是谁
输入语句
SELECT e.ename 雇员,m.ename 管理员 FROM emp e,emp m
WHERE m.empno=e.mgr
AND e.deptno=20;
运行结果
3.不等连接
概念:连接运算符不使用等号的叫不等连接
格式:略
本书P56例2-29,要求查询在部门20工作的雇员的工资及工资等级信息
输入语句
SELECT e.ename ,e.sal,s.grade FROM emp e,salgrade s
WHERE e.sal BETWEEN s.losal AND s.hisal
AND e.deptno=20;
运行结果
说明:以笛卡尔积表去理解不等连接是比较容易的,乘积得到的表,用WHERE指明的条件一条条排除
4.左外连接
左外连接的理解可以细化.
1.左外连接也属于相等连接,ON后面内容判断第一个表的某项属性值和第二表的属性值相等.处理两个表连接的笛卡尔积,得到结果1
2.在结果1中再用WHERE子句筛选,左表(第一个表)的属性值全部保留,第二个表属性值有就填没有就填NULL
=============================内容分割线↓===================================
细化是一种学习方法.当遇到某个学习内容无法消化,考虑把内容细化到能解决的程度.
同时他也是问题解决的方法,当遇到当前问题没办法解决时,考虑把问题细化到能解决的程度.
=============================内容分割线↑===================================
格式(和相等连接类似):
SELECT 列名1,....列名n FROM 表1 LEFT OUTER JOIN 表2 ON
WHERE 条件表达式1,...条件表达式n
举例:本书P56例2-30,要求以dept为左表,查询loc,dept.deptno,emp.deptno,ename,empno,左外连接emp表
输入语句
SELECT loc,dept.deptno,emp.deptno,ename,empno FROM dept LEFT OUTER JOIN emp ON
dept.deptno=emp.deptno
WHERE dept.deptno=10 OR dept.deptno=40;
运行结果
5.右外连接
和左表连接几乎是镜像,不再赘述.
注意:本书例2-30和例2-31的结果是相同的.再看两个查询语句,左表和右表换了位置,查询命令从LEFT OUTER JOIN换成了RIGHT OUTER JOIN,两两互换,结果没变.
此时的左表是emp(FROM后的第一个表名),右表是dept,右外连接后右表(dept)内容全保留
输入语句
SELECT loc,dept.deptno,emp.deptno,ename,empno FROM emp RIGHT OUTER JOIN dept ON
emp.deptno=dept.deptno
WHERE dept.deptno=10 OR dept.deptno=40;
运行结果
小结
连接查询的一点分析
笛卡尔积是连接查询的基础.