千家信息网

ORACLE百例试炼二

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,Oracle系列《二》:多表复杂查询和事务处理多表查询应该注意去除笛卡尔积,一般多个表时会为表起个别名【1】要求查询雇员的编号、姓名、部门编号、部门名称及部门位置SQL> SELECT e.empno
千家信息网最后更新 2026年11月01日ORACLE百例试炼二

Oracle系列《二》:多表复杂查询和事务处理



多表查询应该注意去除笛卡尔积,一般多个表时会为表起个别名

【1】要求查询雇员的编号、姓名、部门编号、部门名称及部门位置

SQL> SELECT e.empno,e.ename,d.deptno,d.dname,d.loc FROM emp e,dept d

WHERE e.deptno = d.deptno;


【2】要求查询每个雇员的姓名、工作、雇员的直接上级领导的姓名(表自关联)

SQL> SELECT e.ename,e.job,m.ename FROM emp e,emp m

WHERE e.mgr = m.empno;


【3】对【2】进行扩充,将雇员所在部门名称同时列出

SQL> SELECT e.ename,e.job,m.ename,d.dname FROM emp e,emp m,dept d

WHERE e.mgr = m.empno AND e.deptno=d.deptno;


【4】查询每个雇员的姓名、工资、部门名称,工资在公司的等级(salgrade),及其领导的姓名所在公司的等级

<1>先确定工资等级表的内容

SQL> SELECT * FROM salgrade;


<2>查询每个雇员的姓名、工资、部门名称和工资在公司的等级

SQL> SELECT e.ename,e.sal,d.dname,s.grade FROM emp e,dept d,salgrade s

WHERE e.deptno=d.deptno AND e.sal BETWEEN s.losal AND s.hisal;


<3>查询其领导姓名及工资所在公司的等级

SQL> SELECT

e.ename,e.sal,d.dname,s.grade,m.ename,m.sal,ms.grade FROM emp e,dept d,salgrade s,emp m,salgrade ms

WHERE e.deptno = d.deptno

AND e.sal BETWEEN s.losal AND s.hisal

AND e.mgr = m.empno

AND m.sal BETWEEN ms.losal AND ms.hisal;


【5】左连接与右连接的概念,"+"在等号左边表示右连接,反之,左连接

查询雇员的编号、姓名及其领导的编号、姓名

SQL> SELECT e.empno,e.ename,m.empno,m.ename FROM emp e,emp m

WHERE e.mgr = m.empno(+); 就发现将KING的那条记录也连过来了







SQL1999语法中有如下几种连接(了解)

1、交叉连接CROSS JOIN,产生笛卡尔积

SQL> SELECT * FROM emp CROSS JOIN dept;

2、自然连接NATURAL JOIN,自动进行关联字段的匹配

SQL> SELECT * FROM emp NATURAL JOIN dept;


3、使用USING子句,直接关联操作列

SQL> SELECT * FROM emp JOIN dept USING(deptno) WHERE deptno=30;

4、使用ON子句,用户自己编写的条件

SQL> SELECT * FORM emp JOIN dept ON(emp.deptno = dept.deptno) WHERE deptno=30;


5、左连接(左外连接、LEFT (OUTER) JOIN)、右连接(右外连接、RIGHT (OUTER) JOIN)








组函数及分组统计

1、COUNT():求出全部记录数

2、MAX():求出一组中最大值

3、MIN():求出最小值

4、AVG():求出平均值

5、SUM():求和


【1】求出每个部门的雇员数量

SQL> SELECT deptno,count(empno) FROM emp

GROUP BY deptno;


【2】按部门分组,并显示部门的名称,及每个部门的员工数

SQL> SELECT d.dname,COUNT(e.empno) FROM emp e,dept d

WHERE e.deptno=d.deptno GROUP BY d.dname;


【3】要求显示平均工资大于2000的部门编号和平均工资

SQL> SELECT deptno,AVG(sal) FROM emp

WHERE AVG(sal)>2000 GROUP BY deptno;

出错,WHERE子句中不能出现分组函数的条件,要使用HAVING子句 上述语句应该改为如下


SQL> SELECT deptno,AVG(sal) FROM emp

GROUP BY deptno

HAVING AVG(sal)>2000


【4】显示非销售人员工作名称以及从事同一工作雇员的月工资总和,

并且要求从事同一工作的雇员月工资合计大于$5000, 输出结果按月工资的合计升序排序

<1>按工作分组,求出非销售人员的月工资总和

SQL> SELECT job,SUM(sal) FROM emp

WHERE job<>'SALESMAN' GROUP BY job;


<2>对分组条件进行限制,然后进行排序,HAVING子句不能使用别名

SQL> SELECT job,SUM(sal) totalSal FROM emp

WHERE job<>'SALESMAN' GROUP BY job

HAVING SUM(sal) > 5000 ORDER BY totalSal;


【5】分组函数可以嵌套使用,但是在SELECT列中就不能再出现该分组条件的列名了

SQL> SELECT deptno,MAX(AVG(sal)) FROM emp

GROUP BY deptno;


出错!修改如下

SQL> SELECT MAX(AVG(sal)) FROM emp

GROUP BY deptno;


【6】查询出比7654工资要高的全部雇员的信息

<1>首先要查询雇员编号7654的工资

SQL> SELECT sal FROM emp WHERE empno=7654;


<2>以上述条件的结果最后后续查询的依据

SQL> SELECT * FROM emp

WHERE sal>(SELECT sal FROM emp WHERE empno=7654);








子查询在操作中分为以下三类:

1、单列子查询:返回的结果是一列的内容

2、单行子查询:返回多个列,也可能是一条记录

3、多行子查询:返回多个记录



【1】要求查询工资比7654高,同时与7788从事相同工作的全部雇员

SQL> SELECT * FROM emp

WHERE sal>(SELECT sal FROM emp WHERE empno=7654)

AND job=(SELECT job FROM emp WHERE empno=7788);



【2】要求查询 部门名称、部门员工数、部门平均工资,部门的最低收入雇员的姓名

<1>查询部门员工数、部门平均工资

SQL> SELECT deptno,COUNT(empno),AVG(sal) FROM emp

GROUP BY deptno;


<2>查询部门的名称,及最低收入雇员姓名,要进行表关联(子查询)

SQL> SELECT d.dname,ed.c,ed.a,e.ename FROM dept d,(

SELECT deptno,COUNT(empno) c,AVG(sal) a,MIN(sal) min FROM emp

GROUP BY deptno) ed, emp e

WHERE d.deptno=ed.deptno AND e.sal = ed.min;


若上述存在两个最低工资的情况,则会出错,在子查询中存在以下3种查询的操作符号

IN:指定一个查询范围,例如查询每个部门的最低工资(返回值有多个)

SQL> SELECT * FROM emp

WHERE sal IN (SELECT MIN(sal) FROM emp GROUP BY deptno);


ANY:=ANY(与IN操作一样)、>ANY(比最小大)、

SQL> SELECT * FROM emp

WHERE sal


ALL: >ALL(比最大要大)、


多行子查询

显示和10号部门从事相同岗位的雇员信息

SQL>select * from emp where job in (select job from emp where deptno=10);








数据库更新操作INSERT、UPDATE、DELETE


【1】复制一张表,例如复制EMP表为MYEMP

SQL> CREATE TABLE MYTEMP AS SELECT * FROM emp;


【2】将编号为7899的雇员的领导取消

SQL> UPDATE myemp SET mgr=null WHERE empno=7899;

【3】更新时,一定要注意不能批量更新(加上WHERE子句),多列更新例子如下

SQL> UPDATE myemp SET mgr=null,comm=null WHERE empno IN(7369,8899);

【4】删除掉全部领取奖金的雇员

SQL> DELECT FROM emp WHERE comm is NOT NULL;


事务处理 ACID

A:Atomicity 原子性:事务中的操作或者都完成,或者都取消

C:Consistency 一致性:事务中的操作保证数据库中的数据不会出现逻辑上不一致的情况

I:Isolation 隔离性:当前的事务与其他未完成的事务是隔离的

D:Durability 持久性:在COMMIT之后,数据永久保存在数据库中,在此之前,事务的操作都可以回滚


验证事务过程:

<1>创建一张临时表,只包含部门10

SQL> CREATE TABLE emp10 AS SELECT * FROM emp WHERE empno=10;


<2>删除emp10中的7782雇员

SQL> DELETE FROM emp10 WHERE empno=7782;

再打开另一个窗口,发现数据还存在,此时如果可以使用以下的两种命令进行事务处理


COMMIT 和 ROLLBACK 提交事务和回滚事务







SQL查询练习


【1】列出至少一个员工的所有部门

SQL> SELECT d.*,ed.cou FROM dept d,(

SELECT deptno,COUNT(empno) cou FROM emp GROUP BY deptno

HAVING COUNT(empno) > 1

) ed

WHERE d.deptno=ed.deptno;



【2】列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门

SQL> SELECT d.deptno,d.dname,e.empno,e.ename

FROM dept d,emp e WHERE d.deptno = e.deptno(+);



【3】列出所有"CLERK"(办事员)的姓名及其部门名称,部门的人数

<1>关联dept表

SQL> SELECT e.ename,d.dname FROM emp e,dept d

WHERE e.deptno=d.deptno and e.job='CLERK';


<2>使用GROUP BY 完成部门分组人数

SQL> SELECT e.ename,d.dname,ed.cou FROM emp e,dept d,

( SELECT deptno,COUNT(empno) cou FROM emp GROUP BY deptno) ed

WHERE job='CLERK' AND e.deptno=d.deptno AND ed.deptno=e.deptno;


部门 查询 工资 雇员 姓名 事务 名称 分组 员工 子句 数据 求出 工作 条件 等级 关联 最低 公司 多个 更新 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广州为想互联网科技有限公司 广州万易互联网科技有限公司 科技互联网企业 互联网巨头科技公司 互联网科技小贷 互联网科技作文 火传媒上海互联网科技 互联网科技股午盘股票涨跌 衡水科技产业互联网平台 央行互联网金融科技公司 贵州叶脉互联网科技有限公司所属行业 健康食品互联网创新科技园项目 恒生互联网科技业指数调整周期 无锡工业互联网科技有限公司 沐思想互联网科技有限公司 半导体是互联网高科技吗 下一代互联网重大应用科技园 互联网科技平台产品运营 艺电能源互联网科技有限公司招聘 绵阳真晨互联网科技有限公司 互联网高科技 中关村互联网科技集团 互联网与新科技 朗涯互联网科技 奔汉互联网科技 互联网金融监管科技 浙江互联网科技研学营 河南猎农互联网科技有限公司 苏州五指互联网络科技有限 张召忠谈中国互联网科技
0