【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;
【3】分组函数可以嵌套使用,但是在SELECT列中就不能再出现该分组条件的列名了
SQL> SELECT deptno,MAX(AVG(sal)) FROM emp
GROUP BY deptno; 出错!修改如下
SQL> SELECT MAX(AVG(sal)) FROM emp
GROUP BY deptno;
【4】查询出比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(比最小大)、 SELECT * FROM emp
WHERE sal
ALL: >ALL(比最大要大)、
SQL多列子查询示例如下
SQL> SELECT * FROM emp
WHERE (sal,NVL(comm,-1)) IN
(SELECT sal,NVL(comm,-1) FROM emp WHERE deptno=20);
数据库更新操作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】列出所有\办事员)的姓名及其部门名称,部门的人数 <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;
Oracle系列《三》:表、(约束)索引、序列、视图的使用 一、创建、删除、修改表
建立表:Oracle中主要数据类型 VARCHAR2、NUMBER、DATE、CLOB(大量文本)、BLOB(图片、音乐、电影)
如果只能复制一张表的结构,但不复制内容,则加上一个不可能成立的条件即可,例如
SQL> CREATE TABLE tmp AS (SELECT * FROM emp WHERE 1==2)
例如创建表Person如下:
CREATE TABLE person( pid VARCHAR2(18), name VARCHAR2(30), age NUMBER(3), birthday DATE,
sex VARCHAR(2) DEFAULT 'M' );