Oracle笔记(六)多表查询(一)

2014-11-24 15:25:25 · 作者: · 浏览: 0

Oracle笔记(六)多表查询
本次预计讲解的知识点
1、 多表查询的操作、限制、笛卡尔积的问题;
2、 统计函数及分组统计的操作;
3、 子查询的操作,并且结合限定查询、数据排序、多表查询、统计查询一起完成各个复杂查询的操作; www.2cto.com
一、多表查询的基本概念
在之前所使用的查询操作之中,都是从一张表之中查询出所需要的内容,那么如果现在一个查询语句需要显示多张表的数据,则就必须应用到多表查询的操作,而多表查询的语法如下:
SELECT [DISTINCT] * | 字段 [别名] [,字段 [别名] ,…]
FROM 表名称 [别名], [表名称 [别名] ,…]
[WHERE 条件(S)]
[ORDER BY 排序字段 [ASC|DESC] [,排序字段 [ASC|DESC] ,…]];
但是如果要进行多表查询之前,首先必须先查询出几个数据 —— 雇员表和部门表中的数据量,这个操作可以通过COUNT()函数完成。
范例:查询emp表中的数据量 ——返回了14条记录
SELECT COUNT(*) FROM emp;
范例:查询dept表中的数据量 ——4条记录
SELECT COUNT(*) FROM dept;
额外补充一点:何为经验? www.2cto.com
在日后的开发之中,很多人都肯定要接触到许多新的 数据库和数据表,那么在这种时候有两种做法:
做法一:新人做法,上来直接输入以下的命令:
SELECT * FROM 表名称;
如果此时数据量较大的话,一上无法浏览数据,二有可能造成系统的死机;
做法二:老人做法,先看一下有多少条记录:
SELECT COUNT(*) FROM 表名称;
如果此时数据量较小,则可以查询全部数据,如果数据量较大则不能直接使用SELECT查询。
现在确定好了emp和dept表中的记录之后,下面完成一个基本的多表查询:
SELECT * FROM emp, dept;
但是现在查询之后发现一共产生了56条记录 = 雇员表的14条记录 * 部门表的4条记录,之所以会造成这样的问题,主要都是由数据库的查询机制所决定的,例如,如下图所示。


本问题在数据库的操作之中被称为笛卡尔积,就表示多张表的数据乘积的意思,但是这种查询结果肯定不是用户所希望的,那么该如何去掉笛卡尔积呢?
最简单的方式是采用关联字段的形式,emp表和dept表之间现在存在了deptno的关联字段,所以现在可以从这个字段上的判断开始。
www.2cto.com

当在查询之中,不同的表中有了相同字段名称的时候,访问这些字段必须加上表名称,即“表.字段”。
SELECT * FROM emp
WHERE emp.deptno=dept.deptno;
此时的查询结果之中已经消除了笛卡尔积,但是现在只属于显示上的消除,而真正笛卡尔积现在依然存在,因为数据库的操作机制就属于逐行的进行数据的判断,那么如果按照这个思路理解的话,现在假设两张表的数据量都很大的话,那么使用这种多表查询的性能。
范例:以sh用户的大数据表为例
SELECT COUNT(*) FROM sales, costs
WHERE sales.prod_id=costs.prod_id;
这两张表即便消除了笛卡尔积的显示,但是本身也会有笛卡尔积的问题,所以最终的查询结果会很慢显示,甚至是不显示,所以通过这道程序一定要记住,多表查询的性能是很差的,当然,性能差是有一个前提的:数据量大。
但是以上的程序也存在一个问题,在之前访问表中字段的时候使用的是“表.字段”名称,那么如果说现在假设表名称很长,例如“yinhexi_diqiu_yazhou_zhongguo_beijing_xicheng_ren”,所以一般在进行多表查询的时候往往都会为表起一个别名,通过别名.字段的方式进行查询。
SELECT * FROM emp e, dept d
WHERE e.deptno=d.deptno;
范例:查询出每一位雇员的编号、姓名、职位、部门名称、位置
1、确定所需要的数据表: www.2cto.com
emp表:可以查询出雇员的编号、姓名、职位;
dept表:可以查询出部门名称和位置;
2、确定表的关联字段:emp.deptno=dept.deptno;
第一步:查询出每一位雇员的编号、姓名、职位
SELECT e.empno, e.ename, e.job
FROM emp e;
第二步:为查询中引入部门表,同时需要增加一个消除笛卡尔积的条件
SELECT e.empno, e.ename, e.job, d.dname, d.loc
FROM emp e, dept, d
WHERE e.deptno=d.deptno;
以后遇到问题,发现没有解决问题的思路,就按照上面的步骤进行,慢慢的分析解决,因为多表查询不可能一次性全部写出,需要逐步分析的。
范例:要求查询出每一位雇员的姓名、职位、领导的姓名。


现在肯定要准备出两个emp表,所以这个时候可以称为emp表的自身关联,按照之前的分析如下:
1、确定所需要的数据表:
emp表(雇员):取得雇员的姓名、职位、领导编号;
emp表(领导):取得雇员的姓名(领导的姓名);
2、确定关联字段:emp.mgr=memp.empno(雇员的领导编号 = 领导(雇员)的雇员编号)
第一步:查询每一位雇员的姓名、职位
SELECT e.ename, e.job
FROM emp e;
第二步:查询领导信息,加入自身关联
SELECT e.ename, e.job, m.ename
FROM emp e, emp m www.2cto.com
WHERE e.mgr=m.empno;
此时的查询结果之中缺少了“KING”的记录,因为KING没有领导,而要想解决这个问题,就需要等待之后讲解的左、右连接的问题了。
范例:查询出每个雇员的编号、姓名、基本工资、职位、领导的姓名、部门名称及位置。
1、确定所需要的数据表:
emp表:每个雇员的编号、姓名、基本工资、职位;
emp表(领导):领导的姓名;
dept表:部门的名称及位置。
2、确定已知的关联字段:
雇员和部门:emp.deptno=dept.deptno;
雇员和领导:emp.mgr=memp.empno;
第一步:查询出每个雇员的编号、姓名、基本工资、职位
SELECT empno, ename, sal, job
FROM emp;
第二步:加入领导的信息,引入自身关联,同时增加消除笛卡尔积的条件
SELECT e.empno, e.ename, e.sal, e.job, m.ename
FROM emp e, emp m
WHERE e.mgr=m.empno;
第三步:加入部门的信息,引入dept表,既然有新的表进来,则需要继续增加消除笛卡尔积的条件
SELECT e.empno, e.ena