表的连接是指在一个SQL语句中通过表与表之间的关连,从一个或多个表中检索相关的数据,大体上表与表之间的连接主要可分四种,分别为相等连接,外连接,不等连接和自连接,本文将主要从以下几个典型的例子来分析Oracle表的两类不同连接方式:
一、内连接
1. 相等连接 通过两个表具有相同意义的列,可以建立相等连接条件。只有连接列上在两个表中都出现且值相等的行才会出现在查询结果中。
例:查询员工信息以及对应的员工所在的部门信息; select * from emp e,dept d
Where e.dept_no=d.deptno
练习:显示工资超过2000的员工信息以及对应的员工的部门名称。
Select e.id,e.first_name,e.salary,d.dept_name
From emp e,dept d
Where e.salary>2000 and e.dept_no=d.deptno
2. 非等值连接
不使用=号进行连接,表间关系是一种非等值的情况
例:显示列出员工的名字、薪水、薪水级别
select e.first_name,e.salary,s.grade
from emp e,salgrade s
where e.salary between losal and hisal;
3. 自连接
当一张表中两个字段之间有关系时,使用自连接,将一张表通过起别名的方式,模拟成两张表,此时一张表中两个字段的关系就转化为两张表字段间的关系。
例:查询出员工的名字,领导名字的对应关系
select e.first_name,m.first_name
from s_emp e,s_emp m
where e.manager_id=m.id;
归纳内连接:会严格匹配数据,遇到空值会造成记录的丢失,需要使用内连接的补充:外连接
二、外连接
对于外连接,Oracle中可以使用“(+)”来表示,9i可以使用LEFT/RIGHT/FULL OUTER JOIN,下面将配合实例一一介绍。除了显示匹配相等连接条件的信息之外,还显示无法匹配相等连接条件的某个表的信息。
外连接采用(+)来识别。
1. 左条件(+) = 右条件;
代表除了显示匹配相等连接条件的信息之外,还显示右条件所在的表中无法匹配相等连接条件的信息。
此时也称为"右外连接".另一种表示方法是:
SELECT ... FROM 表1 RIGHT OUTER JOIN 表2 ON 连接条件
例:查询出部门里的员工名字和领导名字
select e.first_name,m.first_name
from emp e right outer join emp m
on e.manager_id=m.id;
select e.first_name,m.first_name
from emp e ,emp m
where e.manager_id(+)=m.id;
2. 左条件 = 右条件(+)
代表除了显示匹配相等连接条件的信息之外,还显示左条件所在的表中无法匹配相等连接条件的信息。
此时也称为"左外连接"
SELECT ... FROM 表1 LEFT OUTER JOIN 表2 ON 连接条件 例 显示员工信息以及所对应的部门信息
Select * from emp e left outer join dept d
on e.dept_no =d.deptno
select * from emp e,dept d
Where e.dept_no=d.deptno(+)
3.全外连接
保证两边数据一个都不能少,全都匹配,不允许两边添加(+),使用full outer join on···
select e.name,nvl(d.name,’无部门’) as 部门名称
from emp e full outer join dept d
on e.dept_id=d.id;
附加:
常见的笔试题:
删除表中的重复数据
Delete from test where id not in(select max(id) from test group by name);
delete from test where id not in(select min(id) from test group by name);
显示一年中每个季度的开始日期和结束日期
Select rownum no,add_months(trunc(sysdate,’y’),(rownum-1)*3) q_start,
Add_months(trunc(sysdate,’y’),rownum*3)-1 q_end
From s_emp
Where rownum <=4;
从s_emp表中随机返回5条记录
Select * from(select id,first_name,salary from s_emp order by dbms_random.value()) where rownum<=5;
求出一年中包含的天数
Select ‘days in 2013:’ || to_char(
add_months(trunc(sysdate,’y’),12)-1,’DDD’)
as report from dual;
Select ‘days in 2012:’ || to_char(
add_months(trunc(to_date(’2012-01-05’,’yyyy-mm-dd’),’y’),12)-1,’DDD’)
as report from dual;
显示出昨天,今天,明天,精度到时,分,秒
alter session set nls_date_format='yyyy mm dd hh24:mi:ss';
select sysdate-1,sysdate,sysdate+1 from dual;
显示10分钟后的时间,精度到时,分,秒(10分钟换算成多少天)
alter session set nls_date_format='yyyy mm dd hh24:mi:ss';
select sysdate,sysdate+1/144 from dual;
显示上个月的今天,今天,下个月的今天
alter session set nls_date_format='yyyy mm dd hh24:mi:ss';
select add_months(sysdate,-1),sysdate,add_months(sysdate,1) from dual;