您的位置:首页 > 数据库 > Oracle

Oracle学习笔记(四)

2016-06-17 13:54 323 查看
多表查询

一、内连接

(一)语法

select table1.column, table2.column

from table1

join table2

on table1.column_name=table2.column_name;

(二)主外键

主外键作为约束条件,用来保证数据的完整性

主键(primer key)

外键(foreign key)



主键一旦被参照就不能随意删除,fk可以为空,但取值一定,根据参照的表的pk

外键用来表示表间关系,一对多

上图中,dept:主键被参照,称为主表,父表

      emp:外键参照dept表,称为从表,子表

(三)例子

查找叫Smith的人所在的部门名称

select e.ename, d.dname

from emp e join dept d

on e.deptno=d.deptno

where e.ename='SMITH';

(四)内连接原理

(A)t1表和t2表做内连接,连接条件为on t1.c1=t2.c2,假设t1表做驱动表,t2表做匹配表,记录的匹配过程如下:

1.从t1表中读取第一条记录r1,若它的c1值为1

2.根据该值到t2表中查找匹配的记录,即需要遍历t2表,从t2表中的第一条记录开始,若该记录r1的c2列的值等于1,我们就说这两条记录能够匹配上,那么t1的r1和t2的r1组合起来,作为结果集里的一条记录,否则检测t2表中的下一条记录

3.按照方法2依次将t2表中所有的记录检测一遍,只要匹配就放入结果集中

4.从t1表中读取第二条记录,依次重复步骤2和3,产生最终的结果集

(B)t1表和t2表做内连接,连接条件为on t1.c1=t2.c2,假设t1表做驱动表,t2表做匹配表,记录的匹配有如下三种情况:

1.t1表中的某条记录在t2表中找不到任何一条匹配的记录,那么t1表中的该记录不会出现在结果集中

2.t1表中的某记录在t2表中只有一条匹配的记录,那么t1表中的该记录和t2表中匹配的记录组合成新纪录出现在结果集中

3.t1表中的某条记录在t2表中有多条匹配的记录,那么t1表中的该记录会和t2表中每一条匹配的记录组合成新纪录出现在结果集中

(C)内连接的核心

任何一张表里的记录一定要在另一张表中找到匹配的记录,否则不能出现在结果集中

(D)有两种方式都能得到结果集记录

1.一种t1表做驱动表,t2表做匹配表

2.另一种t2表做驱动表,t1表做匹配表

3.无论哪种方式最终得到的结果集都一样,所不同的是效率

(五)内连接的三种形式

1.等值连接

两张表有描述共同属性的列,常见形式为父表的主键和子表的外键相等

select e.ename, e.sal, d.dname

from emp e join dept d

on e.deptno=d.deptno and e.job='MANAGER';

职位是经理(MANAGER)的员工属于哪些部门

先用条件 e.job='MANAGER'对emp表进行过滤,结果集和dept表内连接

如果把查询结果看成一张表,该查询就是把两张表的数据通过表连接的方式合成一张新表

2.非等值连接

(1)可以用between and这样的非等值运算符将两张表中的列写成一个表达式

(2)所谓表之间的关系,实际指表中的行(记录)之间的关系,该关系通过将表中的列写成表达式来体现

select e.ename, e.sal, s.grade

from emp e join salgrade s

on e.sal between s.losal and s.hisal;

列出员工的名字,工资和等级

3.自连接



(1)同一张表的列之中有关系实际反应的是同一张表的行(记录)之间有关系

(2)通过给表起别名将同一张表的列之间的关系转换成不同表的列之间的关系

select worker.ename, manager.ename

from emp worker join emp manager

on worker.mgr=manager.empno;

二、外连接

(一)语法

select table1.column, table2.column

from table1

left/right/full outer join table2

on table1.column_name=table2.column_name;

(二)外连接的原理

t1表和t2表做外连接,连接条件为from t1 left outer join t2 on t1.c1=t2.c2;

t1表必须做驱动表,t2表必须做匹配表

(A)记录的匹配过程如下:

1.从t1表中读取第一条记录r1,若它的c1值为1

2.根据该值到t2表中查找匹配的记录,即需遍历t2表,从t2表中的第一条记录开始,若该记录(r1)的c2列的值等于1,则这两条记录匹配,那么t1的r1和t2的r2组合起来,作为结果集里的一条记录,否则检测t2表中的下一条记录

3.按照方法2依次将t2表中所有的记录检测一遍,只要匹配就放入结果集中,若扫描完后,t1的r1记录在t2表中找不到任何匹配的记录,t2表中模拟一条null记录与t1表中r1组合起来,放入结果集中

4.从t1表中读取第二条记录,依次重复步骤2和3,产生最终的结果集

(B)匹配的情况

1.外连接的结果集=内连接的结果集+t1表中匹配不上的记录和一条null记录的组合

2.外连接的核心可以将驱动表中匹配不上的记录找回来,即一个都不能少

t1 left outer join t2=t2 right outer join t1

t1 right outer join t2=t2 left outer join t1

t1 full outer join t2=t2 full outer join t1

from t1 right outer join t2 on t1.c1=t2.c2

外连接的结果集=内连接的结果集+t2表中匹配不上的记录和一条null记录的组合

from t1 full outer join t2 on t1.c1=t2.c2

外连接的结果集=内连接的结果集+t2表中匹配不上的记录和一条null记录的组合+t1表中匹配不上的记录和一条null记录的组合

(三)例子

select worker.ename, manager.ename

from emp worker left outer join emp manager

on worker.mgr=manager.empno;

列出所有职员,不管有没有经理

select manager.ename

from emp worker

right outer join emp manager

on worker.mgr=manager.empno

where worker.empno is null;

哪些员工无下属(不是领导)

外连接+匹配表pk is null表示否定问题,不是,不包括,等等

select d.dname

from emp e right outer join dept d

on e.deptno=d.deptno

and e.ename='SMITH'

where e.empno is null;

哪些部门没有名字为SMITH的员工

该语句的执行顺序为对emp表先用e.ename='SMITH'进行过滤,再将结果集和dept表做外连接,生成结果集后,再用where条件对该结果进行过滤,产生最终的结果,这里的结果集如下:

结果集=有SMITH的部门(内连接产生的结果集)+没有SMITH的部门(驱动表中匹配不到的记录和null值的结果集)

三、组函数

max/min/avg/sum/count

select avg(sal) from emp;

select sum(sal) from emp;

select max(sal) from emp;

select min(sal) from emp;

select avg(nvl(comm,0)) from emp;

select count(distinct deptno) from emp;

按照部门分组,计算每个部门的薪水总和:

select deptno, sum(sal)

from emp

group by deptno;

按照职位分组,计算每个职位的平均薪水:

select job,avg(sal)

from emp

group by job;

在select后面,所有的非组函数的列必须出现在group by后面

出现在group by后面的列不一定出现在select后面,但是信息不完整

select avg(sal)

from emp

group by job;

结论:select后面的非组函数的列和group by后面的列明保持一致

获得每个部门每个职位的平均薪水

select deptno, job, avg(sal)

from emp

group by deptno,job

order by deptno,job;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: