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(比最小大)、<ANY(比最大小)

SQL> SELECT * FROM emp

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

ALL: >ALL(比最大要大)、<ALL(比最小的小),SQL语句类似上面

多行子查询

显示和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;

时间: 2024-08-25 13:07:49

ORACLE百例试炼二的相关文章

ORACLE百例试炼三

Oracle系列<三>:表.(约束)索引.序列.视图的使用 一.创建.删除.修改表 建立表:Oracle中主要数据类型 VARCHAR2.NUMBER.DATE.CLOB(大量文本).BLOB(图片.音乐.电影) 如果只能复制一张表的结构,但不复制内容,则加上一个不可能成立的条件即可,例如 SQL> CREATE TABLE tmp AS (SELECT * FROM emp WHERE 1>2) 例如创建表Person如下: CREATE TABLE person( pid  V

ORACLE百例试炼四

Oracle系列<四>:数据库的设计分析 一.序列的使用 在很多数据库系统中都存在一个自动增长的列,如果在Oracle中要完成自动增长的功能,只能依靠序列完成 1.  要有创建序列的权限 create sequence 或 create any sequence 2.  创建序列的语法 CREATE SEQUENCE sequence  //创建序列名称 [INCREMENT BY n]  //递增的序列值是n 如果n是正数就递增,如果是负数就递减 默认是1 [START WITH n]   

ORACLE百例试炼一

Oracle系列<一>:简单SQL与单行函数 [1]EMP表内容查询 SQL> SELECT * FROM emp; 出错,原因是没有找到该表,因为该表时SCOTT用户的表,所以查询时应该加上scott.emp就可以了 [2]显示当前用户 SQL> show user [3]查看当前用户的所有表 SQL> SELECT * FROM tab; [4]若想重复执行上一条SQL语句,则在sqlplus命令行下输入"/"即可 [5]查询一张表的结构,例如dept

ORACLE百例试炼五

Oracle系列<五>:SQL综合练习 [1]列出最低薪金大于1500的各种工作及从事此工作的全部雇员人数 select  job,count(*) from emp group by job having min(sal)>1500 [2]列出在部门'SALES'工作的员工姓名 <1>先查询SALES的部门编号 SQL> SELECT deptno FROM dept WHERE dname='SALES'; <2>SELECT ename FROM em

【我的Oracle学习笔记(二)】----- select语句补充

一.多表查询 多表查询是指从多个有关联的表中查询数据,其语法与单表查询类似.一般来说,多表查询的表要用连接联系起来,如果没连接,则查询结果是这多个查询表的笛卡尔积(注释1). 模拟查询雇员姓名和所在部门名称: select [雇员姓名],[部门名称] from [雇员表] a,scott,[部门表] b where a.[部门编号]=b.[部门编号]; 上例中,为每一个查询表指定了别名,便于SQL语句的书写. 模拟查询在”sales“部门工作的雇员其雇员姓名 select [雇员姓名] from

探索Oracle之数据库升级二 11.2.0.3升级到11.2.0.4完整步骤

探索Oracle之数据库升级二  11.2.0.3升级到11.2.0.4完整步骤 说明:         这篇文章主要是记录下单实例环境下Oracle 11.2.0.1升级到11.2.0.3的过程,当然RAC的升级是会有所不同.但是他们每个版本之间升级步骤都是差不多的,先升级Database Software,再升级Oracle Instance. Oracle 11.2.0.4的Patchset No:19852360下载需要有Oracle Support才可以.  Patchset包含有7个

Android应用之《宋词三百首》(二)

接上回,上回我们讲到MainActivity里面将所有的宋词标题和作者显示到界面的ListView中去,我们接下来的工作是通过点击ListView的Item跳转到ContentActivity里面去显示单个宋词的所有内容,跳转代码例如以下: // 为ListView的Item设置点击监听器 mListView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterVi

HBase1.0.0源码分析之请求处理流程分析以Put操作为例(二)

HBase1.0.0源码分析之请求处理流程分析以Put操作为例(二) 1.通过mutate(put)操作,将单个put操作添加到缓冲操作中,这些缓冲操作其实就是Put的父类的一个List的集合.如下: private List<Row> writeAsyncBuffer = new LinkedList<>(); writeAsyncBuffer.add(m); 当writeAsyncBuffer满了之后或者是人为的调用backgroundFlushCommits操作促使缓冲池中的

C语言程序设计百例之第一例

题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. 2.程序源代码: #include <stdio.h> int main(void) { int nFirst, nSecond, nThird; int threeNum; int countNum = 0; for(nFirst = 1; nFirst < 5; nFirst++) for(nSe