多表查询

来源:互联网 发布:代刷网 授权平台源码 编辑:程序博客网 时间:2024/06/06 07:36

多表查询

笛卡尔集表

笛卡尔集表=列数之和,行数之积。

例如有 emp 和 dept 两张表。
这里写图片描述
那么他们的笛卡尔集表为:
这里写图片描述

可以看出:笛卡尔集表中有一些数据是不合法的。

笛卡尔集表在数据库中的体现为:
select emp.ename,dept.dname
from emp,dept; -> 查询出来即为上图所示结果。

因此我们要在笛卡尔集表的基础上进行筛选(使用where子句),从而查询出有效的值和我们想要的数据。
根据不同的筛选方法。 我们分为等值连接查询、非等值连接查询、外连接查询、自连接查询。如下图:
这里写图片描述

本文中范例用到的emp表和dept表:
这里写图片描述

等值连接查询 和 非等值连接查询 -> (内连接查询)

在where子句中进行筛选时只能使用=号。即为等值连接查询。
例如:
显示员工的编号,姓名,部门名。
select emp.empno,emp.ename,dept.dname,dept.deptno
from emp,dept
where emp.deptno = dept.deptno;

在where子句中进行筛选时不能使用=号,其它符号可以,例如:>=,<=,<>,betwen and等,即为非等值连接查询。
select e.empno,e.ename,e.sal,s.grade
from emp e,salgrade s
where e.sal between s.losal and s.hisal;

等值连接查询和非等值连接查询都属于内连接查询。而内连接查询只能查询出符合条件的记录

外连接查询

外连接查询分为左外连接查询和右外连接查询。那么何为外连接查询呢?
外连接查询->既能查询出符合条件的记录,也能根据一方强行将另一个方查询出来。

例如->按部门10,20,30,40号,统计各部门员工人数,要求显示部门号,部门名,人数。
观察上面两张表40部门,很明显,没有员工属于他, 但是我们还是想在显示结果时显示出它, 那么就需要使用外连接来实现了(即强行将另一个方员工查询出来)。

使用左外连接查询完成:

在MySQL和Oracle中我们都可以这样写:
select dept.deptno “部门号”,dept.dname “部门名”,count(emp.empno) “人数”
from dept
left join emp on(dept.deptno = emp.deptno)
group by dept.deptno,dept.dname;

这里写图片描述

Oracle对于外连接查询还有其特殊的语法–利用:(+)。
select dept.deptno “部门号”,dept.dname “部门名”,count(emp.empno) “人数”
from dept,emp
where dept.deptno = emp.deptno(+)
group by dept.deptno,dept.dname;
结果与上面一样, 不过oracle推荐我们使用上面的那一种

可以看出(+)的放置位置应在数据缺少的一边,我们可以理解为这样来维持平衡。就像下图:
这里写图片描述

使用右外连接查询完成:

在MySQL和Oracle中我们都可以这样写:
select dept.deptno “部门号”,dept.dname “部门名”,count(emp.empno) “人数”
from emp
right join dept on(dept.deptno = emp.deptno)
group by dept.deptno,dept.dname;

对于oracle的特殊语法,也是颠倒一下就可以了:
select dept.deptno “部门号”,dept.dname “部门名”,count(emp.empno) “人数”
from dept,emp
where emp.deptno(+) = dept.deptno
group by dept.deptno,dept.dname;

自连接查询

连接的表都是同一个表,在自连接查询中我们可以使用外连接、内连接查询。
典型的就是把一张表看成两张表。自连接查询一般用在在一张表中,表的数据之间是有关系的。

例如上面的emp表, 我们把empno 和MCR字段截取出来看,他们就是有关系的.
这里写图片描述
我们现在有一个需求, 从emp这张表中查询出,并显示像“SMITH的上级是FORD”这种格式”。
这就需要用到自连接查询

解决办法是将emp看成两张表,然后查询:

select users.ename || ‘的上级是’ ||boss.ename
from emp users,emp boss
where users.mgr = boss.empno;

为了显示出KING的上级,我们可以使用外连接查询
基于上述问题,将KING的上级是“”显示出来
select users.ename || ‘的上级是’ ||boss.ename
from emp users,emp boss
where users.mgr = boss.empno(+);

0 0
原创粉丝点击