龙空技术网

其实Oracle并不难——这十天,跟着我一起学习数据库(第六天)

春春爱太阳 156

前言:

今天我们对“oracle union all order by”大约比较着重,兄弟们都想要了解一些“oracle union all order by”的相关文章。那么小编在网络上搜集了一些对于“oracle union all order by””的相关文章,希望小伙伴们能喜欢,咱们快快来学习一下吧!

/*

集合运算:查询结果可以作为一个集合。

查询结果集与查询结果集之间的运算;

1、联合(UNION)运算

返回由任一查询结果集包含的行,并且去除重复行,并且按照查询结果集的第一列升序排序。

使用原则:

多个被联合的查询语句所选择的列数和列的数据类型必须一致,列的名字不必相同。

如果多个查询结果都有NULL值,整个结果中只包含一个NULL值。

每个查询不能包含自己的Order by子句,只能在联合之后使用Order by子句。

union all的使用:

返回由任一查询结果集包含的行,并且包含重复行,默认情况下不对结果集进行排序 。

与union的区别:

union all 不排序、不剔掉重复;

2、交集运算- INTERSECT 返回多个查询结果集的公有行(多个结果集中都包含的行)。

使用原则

多个查询语句所选择的列数和列的数据类型必须一致,列的名字不必相同。

相交运算不忽略空值。

3、 相减运算 - MINUS

返回第一个查询结果集中存在 而第二个查询结果集中不存在的行记录。

(从第一个查询结果集中剔除也在第二个查询结果集中出现的记录,第一个结果集剩余的记录就是相减运算的结果)

使用原则

多个查询语句所选择的列数和列的数据类型必须一致,列的名字不必相同。

相减运算不忽略空值。

使用集合相减运算可以进行分页查询;

==============================================

4、相关子查询

就是在嵌套子查询基础上,子查询中的where条件使用到了父查询表中的字段值;

父查询和子查询之间通过子查询的where有条件过滤相关关系;

5、exists 和 not exists的相关子查询的用法

exists和not exists的相关子查询返回的是一个判定结果,判定结果 true或false;

如果相关子查询查询到了结果,则返回true;

如果相关子查询没有查询到结果,则返回false;

使用exists关键字,

如果相关子查询返回true,则主查询中对应的记录作为结果集的内容;

使用not exists关键字,

如果相关子查询返回false,则主查询中对应的记录作为结果集的内容;

exists和not exists可以认为类似于java 的if语句,相关子查询相当于是if语句的判定表达式;

6、层次查询(树状递归查询)

按照字段之间的树状层次关系进行查询;

语法:

SELECT [LEVEL], column, expr...

FROM table

[WHERE condition(s)]

[START WITH condition(s)]

[CONNECT BY PRIOR condition(s)] ;

解析:

LEVEL:节点的层次,伪列,由查询的起点开始算起为1,依次类推。

FROM table:指定表、视图或包含列的快照,你只能从单独的一个表中选择。

WHERE: 限制返回的行。

Condition:是一个比较式。

START WITH:指定层次的根行 (起点)。这个子句对于一个正确的分级查询是必须的。

CONNECT BY PRIOR:指定存在父行与子行的关系列。对于分级查询该子句是必须的。

例如:CONNECT BY PRIOR mgr = empno

表示 当前记录的mgr是下一个层次的记录的empno;

当前记录的mgr字段的值是哪个员工的empno值;

例如:CONNECT BY PRIOR empno = mgr

表示我的empno的值是谁的mgr值;

注意: = 左边的属性是父记录的属性;

= 右边的属性是子记录的属性;

*/

-----------------------------------PPT8集合运算-----------------------------------------------------------------

----测试数据准备脚本

CREATE TABLE emp_jobhistory(

id NUMBER,--流水号

empno NUMBER,--员工编号

job VARCHAR2(9),--岗位

begindate DATE,--开始日期

sal Number(7,2)--在该岗位时工资

)

---插入如下数据:

INSERT INTO emp_jobhistory VALUES(1,7839,'TRAINEE','17-11月-81',500);

INSERT INTO emp_jobhistory VALUES(2,7839,'SALESMAN','17-2月-82',1800);

INSERT INTO emp_jobhistory VALUES(3,7839,'CLERK','17-2月-83',2000);

INSERT INTO emp_jobhistory VALUES(4,7839,'SALESMAN','17-2月-85',1800);

INSERT INTO emp_jobhistory VALUES(5,7839, 'MANAGER','17-2月-87',3000);

--union运算

select * from emp_jobhistory;

--查询编号为7839的员工当前工资、岗位和历史工资、岗位

--当前岗位和工资

select e.job,e.sal from emp e where e.empno=7839;

--历史岗位和工资

select ej.job,ej.sal from emp_jobhistory ej where ej.empno=7839;

--union并集运算

select e.job,e.sal from emp e where e.empno=7839

union

select ej.job,ej.sal from emp_jobhistory ej where ej.empno=7839;

---查询哪些员工做过岗位调动

select e.empno from emp e

intersect

select ej.empno from emp_jobhistory ej;

---查询哪些员工没有做过岗位调动

select e.empno from emp e

minus

select ej.empno from emp_jobhistory ej;

---分页查询

SELECT ROWNUM RN,E.* FROM EMP E;

SELECT ROWNUM RN,E.* FROM EMP E WHERE E.DEPTNO=30;

---分页显示;每页显示5条记录:要求显示EMP表中的第1-5条记录

SELECT ROWNUM RN,E.* FROM EMP E WHERE ROWNUM<=5;

---分页显示;每页显示5条记录:要求显示EMP表中的第6-10条记录(产生是在有了1-5的基础上才有6-10)

SELECT ROWNUM RN,E.* FROM EMP E WHERE ROWNUM>5 AND ROWNUM<=10;---不正确

---使用子查询进行分页显示:每页显示5条记录:要求显示EMP表中的第6-10条记录

SELECT * FROM (SELECT ROWNUM RN,E.* FROM EMP E) T WHERE T.RN>5 AND T.RN<=10;

--使用集合相减运算进行分页查询

SELECT ROWNUM RN,E.* FROM EMP E WHERE ROWNUM<=10

minus

SELECT ROWNUM RN,E.* FROM EMP E WHERE ROWNUM<=5;

-------------------------------PPT9高级子查询---------------------------------------------------------------------

--相关子查询

--1.查询比自己职位平均工资高的员工姓名、职位,部门名称,职位平均工资

-----嵌套子查询

SELECT E.ENAME,E.JOB,D.DNAME,MM.AVGSAL FROM EMP E

JOIN DEPT D ON E.DEPTNO=D.DEPTNO

JOIN (SELECT E.JOB MMJOB,AVG(NVL(E.SAL,0)) AVGSAL FROM EMP E GROUP BY E.JOB) MM ON E.JOB=MM.MMJOB

WHERE E.SAL>MM.AVGSAL ;

-----相关子查询

SELECT E.ENAME,E.JOB,D.DNAME,E.SAL FROM EMP E

JOIN DEPT D ON E.DEPTNO=D.DEPTNO

WHERE E.SAL>(SELECT AVG(NVL(E1.SAL,0)) AVGSAL FROM EMP E1 WHERE E.JOB=E1.JOB);

----例如;查询至少调过2次岗位的员工编号,姓名,岗位

select e.empno,e.ename,e.job

from emp e

where 2<=(select count(*) from emp_jobhistory ej where ej.empno=e.empno);

-----使用exists 和not exists的相关子查询

--例:查询那些人是经理?

select * from emp e where exists (select * from emp m where m.mgr=e.empno);

--例:查询那些人不是经理?

select * from emp e where not exists (select * from emp m where m.mgr=e.empno);

---------------------------------PPT10层次查询-------------------------------------------------------------------

---树状层次递归查询

select * from emp e;

select e.empno,e.ename,e.job,e.mgr

from emp e

start with e.ename='KING'

connect by prior e.empno=e.mgr;

--从下往上查

select e.empno,e.ename,e.job,e.mgr

from emp e

start with e.empno=7876

connect by prior e.mgr=e.empno;

------------------------------PPT8与PPT9与PPT10练习题与课后作业---------------------------------------------------------------------

---************PPT8练习1******************--

--1.分别使用联合运算及完全联合运算完成,按照时间升序顺序,查询员工7839的工作岗位列表。

--联合运算

select e.hiredate,e.empno,e.job from emp e where e.empno=7839

union

select ej.begindate,ej.empno,ej.job from emp_jobhistory ej where ej.empno=7839;

---完全联合运算

select e.hiredate,e.empno,e.job from emp e where e.empno=7839

union all

select ej.begindate,ej.empno,ej.job from emp_jobhistory ej where ej.empno=7839;

--2.使用多表连接,查询每个部门的部门编号,部门人数,没有人数的部门显示0。

select d.deptno,count(e.empno)

from dept d

full join emp e on d.deptno=e.deptno

group by d.deptno

order by d.deptno;

--3.使用联合运算,查询每个部门的部门编号,部门人数,没有人数的部门显示0。

select e.deptno,count(*)

from emp e

group by e.deptno

union

select d.deptno,0

from dept d

where d.deptno not in(

select distinct nvl(e2.deptno,0)from emp e2)

group by d.deptno;

--4.使用联合运算,查询10号部门及20号部门的员工姓名,部门编号。

select e.ename,e.deptno from emp e where e.deptno=10 union

select e.ename,e.deptno from emp e where e.deptno=20;

--5.使用集合运算,输出PPT中的效果?

select d.deptno "部门",d.loc "工作地点",null "员工姓名",null "入职日期" from dept d

union

select e.deptno,null,e.ename,e.hiredate from emp e;

---************PPT8课后作业******************--

--1.用集合运算,列出不包含job为SALESMAN 的部门的部门号。

select e.deptno,e.job from emp e minus

select e.deptno,e.job from emp e where e.job='SALESMAN';

--2.写一个联合查询,列出下面的信息:???????--->!!!!!!

--EMP表中所有雇员的名字和部门编号,不管他们是否属于任何部门。

--DEPT表中的所有部门编号和部门名称,不管他们是否有员工。

select e.ename,e.deptno,null dname from emp e union

select null,d.deptno,d.dname from dept d;

--3.用集合运算查询出职位为SALESMAN和部门编号为10的人员编号、姓名、职位,不排除重复结果。

select e.empno,e.ename,e.job from emp e where e.job='SALESMAN'

union all

select e.empno,e.ename,e.job from emp e where e.deptno=10;

--4.用集合查询出部门为10和20的所有人员编号、姓名、所在部门名称。?????

select e.empno,e.ename,d.dname from emp e,dept d where e.deptno=d.deptno and e.deptno=10

union all

select e.empno,e.ename,d.dname from emp e,dept d where e.deptno=d.deptno and e.deptno=20;

---************ppt9练习1******************--

--如下练习,使用相关子查询完成

--1.查询比所在职位平均工资高的员工姓名,职位。

SELECT E.ENAME,E.JOB FROM EMP E

WHERE E.SAL>(SELECT AVG(NVL(E1.SAL,0)) AVGSAL FROM EMP E1 WHERE E.JOB=E1.JOB);

--2.查询工资为其部门最低工资的员工编号,姓名,工资。

select e.empno,e.ename,e.sal

from emp e

where e.sal=(select min(nvl(e1.sal,0)) from emp e1 where nvl(e1.deptno,0)=nvl(e.deptno,0));

---************ppt9练习2******************--

--如下练习,用相关子查询完成

--1.查询所有雇员编号,名字和部门名字。!!!!!!!!!!!

select e.empno,e.ename,(select d.dname from dept d where d.deptno=e.deptno) from emp e;

--2.查询哪些员工是经理?

select * from emp e where exists(select * from emp m where m.mgr=e.empno);

--3.查询哪些员工不是经理?

select * from emp e where not exists(select * from emp m where m.mgr=e.empno);

--4.查询每个部门工资最低的两个员工编号,姓名,工资。

--注意算法思想(需要完善)

select e.empno,e.ename,e.sal,e.deptno

from emp e

where (select count(empno)from emp e2 where

e2.deptno=e.deptno and e2.sal<e.sal)<=1;

-----(完善版)

select e2.ename,e2.sal,e2.deptno

from (select rownum rn,e22.* from(select e.sal,e.deptno,e.ename from emp e order by e.sal) e22) e2

where 1>=(select count(*)from (select rownum rn,e11.* from(select e.sal,e.deptno,e.ename from emp e order by e.sal) e11)e1

where e1.deptno=e2.deptno and e2.rn>e1.rn);

---************ppt9练习3******************--

--如下练习,用exists或not exists完成

--1.列出至少有一个雇员的所有部门名称。

select d.dname

from dept d

where exists(select * from emp e where e.deptno=d.deptno);

--2.列出一个雇员都没有的所有部门名称。

select d.dname

from dept d

where not exists(select * from emp e where e.deptno=d.deptno);

---************ppt9课后作业******************--

--如下练习,使用相关子查询完成。

--1.查询薪水多于他所在部门平均薪水的雇员名字,部门号。

select e.ename,e.deptno

from emp e

where e.sal>(select avg(nvl(ee.sal,0))from emp ee where ee.deptno=e.deptno);

--2.查询员工姓名和直接上级的名字。!!!!!!!!

select e.ename,(select m.ename from emp m where e.mgr=m.empno)

from emp e;

--3.查询每个部门工资最高的员工姓名,工资。

select e.ename,e.sal

from emp e

where e.sal=(select max(nvl(ee.sal,0))from emp ee where nvl(ee.deptno,0)=nvl(e.deptno,0));

--4.查询每个部门工资前两名高的员工姓名,工资(扩展作业)

select e.empno,e.ename,e.sal,e.deptno

from emp e

where (select count(empno)from emp e2 where

e2.deptno=e.deptno and e2.sal>e.sal)<=1;

---************PPT10课后作业******************--

--1.产生一个报告显示 BLAKE的所有下级(包括直接和间接下级)雇员的名字、薪水和部门号。

select e.ename,e.sal,e.deptno

from emp e

start with e.ename='BLAKE'

connect by prior e.empno=e.mgr;

--2.创建一个报告显示对于雇员 SMITH 经理的层次,包括级别和姓名,首先显示他的直接经理。?????

select level,e.ename

from emp e

where e.ename<>'SMITH'

start with e.ename='SMITH'

connect by prior e.mgr=e.empno;

--3.创建一个缩进报告显示经理层次,从名字为 KING的雇员开始,显示雇员的名字、经理ID和部门ID。

select e.ename,e.mgr,e.deptno,lpad (ename,length(ename)+(LEVEL-1)*2,'*')

from emp e

start with e.ename='KING'

connect by prior e.empno=e.mgr;

--4.产生一个公司组织图表显示经理层次。从最顶级的人开始,排除所有job为CLERK的人,还要排除FORD和那些对FORD报告的雇员。?????

select e.ename,e.mgr,e.deptno,lpad (ename,length(ename)+(LEVEL-1)*2,'*')

from emp e

where e.job<>'CLERK'

start with e.ename='KING'

connect by prior e.empno=e.mgr and e.ename<>'FORD';

------

select lpad (ename||'_'||e.mgr||'_'||e.deptno,length(ename||'_'||e.mgr||'_'||e.deptno)+(LEVEL*2)-2,'-')

from emp e

where e.job<>'CLERK'

start with e.ename=(select ename from emp where mgr is null)

connect by prior e.empno=e.mgr and e.ename<>'FORD';

---对于此题e.job<>'CLERK'的位置是错误的---

select lpad (ename||'_'||e.mgr||'_'||e.deptno,length(ename||'_'||e.mgr||'_'||e.deptno)+(LEVEL*2)-2,'-')

from emp e

start with e.ename='KING'

connect by prior e.empno=e.mgr and e.ename<>'FORD' and e.job<>'CLERK';

标签: #oracle union all order by #oracle union和union all区别