oracle基础知识(二)
2012-04-01 13:39
375 查看
第五章 分组函数 -- 分组函数会对结果集中的一组记录计算一次,每一组只返回一个结果 1. MAX(列|表达式) MIN(列|表达式) 练习:查询emp中员工工资的最大值 SELECT MAX(sal), MIN(sal) FROM emp; 2. SUM -- 求和 AVG -- 取平均值 练习:查询emp表中20部门员工的工资总和 SELECT SUM(sal) FROM emp WHERE deptno = 20; -- 所有的分组函数都是忽略空值 练习:查询emp表中员工平均补助(comm) SELECT AVG(nvl(comm, 0)) FROM emp; SELECT 550 *14 FROM dual; 3. COUNT -- 计数 练习:查询emp表中30部门的员工数 SELECT COUNT(*) FROM emp WHERE deptno = 30; 练习:查询emp表中员工所在的部门有几个 SELECT COUNT(DISTINCT deptno) FROM emp; 练习:查询emp表中各个部门的工资的最大值 SELECT deptno, MAX(sal) FROM emp GROUP BY deptno ORDER BY deptno; 练习:查询emp表中各个职位员工工资的平均值 SELECT job, AVG(sal) FROM emp GROUP BY job; -- 必须要使用子查询 练习:查询emp表中各个部门的工资最高的员工的姓名以及工资 SELECT ename, deptno, MAX(sal) FROM emp GROUP BY ename, deptno ORDER BY deptno; -- 两个原则 -- 1. group by 子句中出现的列,可以不在select子句中出现; -- 2. select 子句出现的非分组函数列,一定要在group by子句中出现; 练习:查询emp表中平均工资在2000以上的部门编号和平均工资 SELECT deptno, AVG(sal) FROM emp --WHERE AVG(sal) > 2000 GROUP BY deptno HAVING AVG(sal) > 2000; -- 在where子句中不能出现对分组函数结果的判断 -- 对分组函数结果的筛选需要在having子句中 -- 是SQL语句的执行顺序决定的 练习:查询emp表中员工数多于5人的部门编号以及员工数 SELECT deptno, COUNT(*) FROM emp GROUP BY deptno HAVING COUNT(*) > 5; -- 分组函数的嵌套(最多嵌套两层) 练习:查询emp表中各部门的平均人数 SELECT AVG(COUNT(*)) FROM emp GROUP BY deptno;
第六章 多表查询 -- 笛卡尔积 -- A = {a, b} -- B = {1,2,3} -- A × B = {(a, 1), (a, 2),(a, 3),(b, 1),(b, 2),(b, 3)} -- 1. 笛卡尔积元素数量非常庞大,非常耗费系统资源 -- 2. 有意义的数据只占一小部分 -- 结论:在多表查询中一定要避免产生笛卡尔积 -- 方法:一定要为连接的表设定连接条件,两个表连接,至少需要1个连接条件。 -- 连接条件:一般是两个表的公共字段。 -- 公共字段:(狭义)两个表中列名和列的数据类型都相同的那些列; -- (广义)两个表中意义相同的那些列 1. 等值连接(连接条件用=来判断的称之为等值连接) 练习:查询emp表中员工姓名,部门编号以及部门名称 SELECT emp.ename, emp.deptno, dept.deptno, dept.dname FROM emp, dept WHERE emp.deptno = dept.deptno ORDER BY emp.ename; -- 表别名 -- 表名 表别名 -- 表别名中不能包含特殊字符 -- 如果在SQL中给表起了别名了,那么在当前的SQL的任何地方都不能再使用表名,只能 -- 引用表别名 SELECT e.ename, e.deptno, d.deptno, d.dname FROM emp e, dept d WHERE e.deptno = d.deptno ORDER BY e.ename; 2. 不等值连接(连接条件不是用=进行判断) 练习:查询emp表中员工姓名,工资以及工资等级 SELECT e.ename, e.sal, s.grade FROM emp e, salgrade s WHERE e.sal BETWEEN s.losal AND s.hisal ORDER BY e.ename; 练习:查询emp表中20部门员工的姓名,工资,部门名称以及工资等级 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 AND E.DEPTNO = 20; 3. 外连接 -- 外连接的符号(+)永远是在连接条件的缺乏表的一端,要查询哪个表的全部记录,另一张表就是缺乏表 练习:列出所有部门名称和员工的姓名,即使这个部门没有员工 SELECT d.dname, e.ename FROM emp e, dept d WHERE e.deptno(+) = d.deptno ORDER BY d.dname; 练习:查询emp表中员工的姓名和部门编号,即使这个员工没有部门 SELECT d.dname, e.ename FROM emp e, dept d WHERE e.deptno = d.deptno(+) ORDER BY d.dname; 练习:查询没有员工部门的名称 SELECT D.DNAME FROM EMP E, DEPT D WHERE E.DEPTNO(+) = D.DEPTNO AND ENAME IS NULL ORDER BY D.DNAME; 作业:查询没有部门员工的姓名 4. 自连接 -- 查询结果和条件都需要从同一张表中查询的问题 -- 用自连接 -- 语法晦涩,不常用。 -- 日常工作中我们通常用子查询来代替自连接 练习:查询emp表中和SMITH同部门的员工信息,不包括SMITH SELECT A.* FROM EMP A, EMP B WHERE A.DEPTNO = B.DEPTNO AND B.ENAME = 'SMITH' AND A.ENAME <> 'SMITH';
第七章 子查询 -- 查询结果和条件都需要从同一个表中查出来的问题 练习:查询emp表中和SMITH同部门的员工信息,不包括SMITH SELECT * FROM EMP WHERE ENAME <> 'SMITH' AND DEPTNO = (SELECT DEPTNO FROM EMP WHERE ENAME = 'SMITH'); 1. 子查询的分类 a. 单行子查询 - 子查询的结果集是一行一列,可以使用单行比较运算符进行比较 练习:查询emp表中和SCOTT部门相同,且同领导的员工信息,不包括SMITH; SELECT * FROM emp WHERE ename <> 'SCOTT' AND deptno = (SELECT deptno FROM emp WHERE ename = 'SCOTT') AND mgr = (SELECT mgr FROM emp WHERE ename = 'SCOTT'); 练习:查询emp表中部门人数多于平均部门人数的部门编号和人数 SELECT DEPTNO, COUNT(*) FROM EMP GROUP BY DEPTNO HAVING COUNT(*) > (SELECT AVG(COUNT(*)) FROM EMP GROUP BY DEPTNO); b. 多行子查询 - 子查询的结果集是多行一列的,不能使用单行比较运算符,要使用in 练习:查询emp表中哪些员工是领导,列出他们的信息 SELECT * FROM emp WHERE empno IN (SELECT mgr FROM emp); 练习:查询emp表中哪些员工不是领导,列出他们的信息 SELECT * FROM emp WHERE empno NOT IN (SELECT mgr FROM emp WHERE mgr IS NOT NULL); -- 1. 子查询结果集中出现了null -- 2. not in不忽略空值,在子查询中不能出现空值 a IN (1, 2, NULL) ==> a = 1 OR a = 2 OR a = NULL a NOT IN (1, 2, NULL) ==> a <> 1 AND a <>2 AND a <> NULL c. 多列子查询 - 查询结果集是多行多列形式 练习:查询emp表中各个部门的工资最高的员工的姓名以及工资 SELECT deptno, ename, sal FROM emp WHERE (deptno, sal) IN (SELECT deptno, MAX(sal) FROM emp GROUP BY deptno) ORDER BY deptno; (a,b) IN ((1,1), (2,2),(3,3)); ==> a = 1 AND b = 1 OR a = 2 AND b = 2 OR a = 3 AND b = 3; 2. FROM 子句中的子查询 -- 内联视图 - 视图:是一个虚表。视图也是表,所以和表的操作一样。但是视图没有实体数据,只是表的另一种表现方式 -- From子句中的子查询一定要给它起一个别名,作为视图名 -- 如果内联视图中出现了函数列或表达式列,一定要给这样的列起一个别名,就作为对应列的列名 SELECT e.deptno, e.ename, e.sal FROM emp e, (SELECT deptno, MAX(sal) maxsal FROM emp GROUP BY deptno) a WHERE e.deptno = a.deptno AND e.sal = a.maxsal ORDER BY e.deptno; 练习:查询emp表中各个部门的工资最高的员工的姓名,工资以及部门名称 SELECT e.deptno, e.ename, e.sal, d.dname FROM emp e, (SELECT deptno, MAX(sal) maxsal FROM emp GROUP BY deptno) a, dept d WHERE e.deptno = a.deptno AND e.sal = a.maxsal AND e.deptno = d.deptno ORDER BY e.deptno; SELECT B.ENAME, B.SAL, B.DNAME FROM (SELECT E.ENAME, E.SAL, D.DNAME, E.DEPTNO FROM EMP E, DEPT D WHERE E.DEPTNO = D.DEPTNO) B, (SELECT DEPTNO, MAX(SAL) MAXSAL FROM EMP GROUP BY DEPTNO) A WHERE A.DEPTNO = B.DEPTNO AND A.MAXSAL = B.SAL; -- Top-N问题 -- 伪列 rownum -- 所有的查询结果集中都有这样一个伪列 -- 作用是给结果集的记录进行编号 SELECT ROWNUM, dname FROM dept; -- 1. rownum编号是在排序之前已经编好的。 练习:查询emp表中工资由高到低排在前三位的员工的信息 SELECT rownum, a.ename, a.sal FROM (SELECT ename, sal FROM emp ORDER BY sal DESC) a WHERE ROWNUM <= 3; -- 2. rownum 只能用 < 或<=来判断,不能用>或>=来判断,如果用=判断,只能=1 -- rownum 会动态重新编号 练习:查询emp表中工资由高到低排在4~6位的员工的信息 SELECT b.* FROM (SELECT ROWNUM r,a.ename bname,a.sal bsal FROM (SELECT ename,sal FROM emp ORDER BY sal DESC ) a WHERE ROWNUM <=6 ) b WHERE b.r>=4 SELECT B.* FROM (SELECT ROWNUM R, A.ENAME, A.SAL FROM (SELECT ENAME, SAL FROM EMP ORDER BY SAL DESC) A WHERE ROWNUM <= 6) B WHERE B.R >= 4; -- 分页问题 -- CREATE TABLE TEST(N NUMBER); 表中的数据都是正整数,而且不重复 SELECT * FROM TEST ORDER BY N; 写一个SQL语句查询所有连续号码段的起始和结束号码 minnum maxnum 3 5 7 10 12 13 1. 方法1 SELECT AA.N MINNUM, BB.N MAXNUM FROM (SELECT ROWNUM R, A.N FROM (SELECT N FROM TEST WHERE (N - 1) NOT IN (SELECT N FROM TEST) ORDER BY N) A) AA, (SELECT ROWNUM R, B.N FROM (SELECT N FROM TEST WHERE (N + 1) NOT IN (SELECT N FROM TEST) ORDER BY N) B) BB WHERE AA.R = BB.R; 2. 方法2 数据 - 数列 = 结果 n m n-m n+1 m+1 n-m n+2 m+2 n-m n+4 m+3 n-m+1 n+5 m+4 n-m+1 n+6 m+5 n-m+1 n+9 m+6 n-m+3 n+10 m+7 n-m+3 SELECT MIN(B.N) MINNUM, MAX(B.N) MAXNUM FROM (SELECT A.N - ROWNUM R, A.N FROM (SELECT N FROM TEST ORDER BY N) A) B GROUP BY B.R ORDER BY MINNUM; SELECT MIN(A.N) MINNUM, MAX(A.N) MAXNUM FROM (SELECT N FROM TEST ORDER BY N) A GROUP BY A.N - ROWNUM ORDER BY MINNUM;
第八章 数据操作与事务控制 一. 数据插入 练习:向DEPT表中插入记录,编号 50, 部门名称 '实训', 部门所在地 '沈阳' INSERT INTO dept (dname, deptno, loc) VALUES ('实训', 50, '沈阳'); INSERT INTO dept VALUES (51, '实训', '沈阳'); 练习:向DEPT表中插入记录,编号 60, 部门名称 '商用', 部门所在地待定 -- 1. 直接用null关键字 INSERT INTO dept VALUES (60, '商用', NULL); -- 2. 可以用两个连续的单引号来代表空值 INSERT INTO dept VALUES (61, '商用', ''); -- 3. 可以在指定列表的时候忽略空值列,被忽略的列如果没有设定默认值的话,就会插入空值 INSERT INTO dept (deptno, dname) VALUES (62, '商用'); 练习:将自己的信息插入到emp表中(2012-3-5)。 INSERT INTO emp VALUES (9999, 'Liu', 'CLERK', 7788, to_date('2012-3-5', 'YYYY-MM-DD'), 5001, NULL, 10); - 插入多条数据 INSERT INTO emp1 SELECT * FROM emp WHERE deptno = 30; 二. 更新数据 练习:把emp表中scott的工资更新成3100 UPDATE emp SET sal = 3100 WHERE ename = 'SCOTT'; 练习:给emp表中SMITH涨工资100 UPDATE emp SET sal = sal + 100 WHERE ename = 'SMITH'; 练习:将SMITH的领导,部门更新跟SCOTT一样 UPDATE emp SET mgr = (SELECT mgr FROM emp WHERE ename = 'SCOTT') , deptno = (SELECT deptno FROM emp WHERE ename = 'SCOTT') WHERE ename = 'SMITH'; 练习:给30部门工资最低的员工涨100 UPDATE emp SET sal =sal + 100 WHERE deptno = 30 AND sal = (SELECT MIN(sal) FROM emp WHERE deptno = 30); SELECT * FROM emp; 练习:将自己的部门调到20部门,工资更新成20部门的平均工资 + 100,并四舍五入到个位 三. 删除数据 DELETE [FROM] 表名 [WHERE 条件]; DELETE FROM emp1; -- 删除emp1所有数据 练习:将本部门工资比自己高的员工记录删除 DELETE FROM EMP WHERE EMPNO IN (SELECT EMPNO FROM EMP E, (SELECT DEPTNO, SAL FROM EMP WHERE EMPNO = 9999) A WHERE E.DEPTNO = A.DEPTNO AND E.SAL > A.SAL);
第九章 表和约束(DDL) 一. CREATE -- 作用:创建数据库对象 -- create DDL语句,隐式提交,不能回滚 CREATE TABLE [SCHEMA.]表名 -- schema方案名(用户名) ( 列名1 数据类型1 [DEFAULT 表达式], 列名2 数据类型2 [DEFAULT 表达式], ... 列名N 数据类型N [DEFAULT 表达式] ); - 数据类型 -1. 数字型 - NUMBER[(p[, s])] - - p 定义了数字的总长度 - - s 定义了小数位的长度 - 例子 NUMBER(7,2) - NUMBER(4) - NUMBER - 2. 字符型 - a. VARCHAR2(n) - 可变长度的字符类型 - - n代表字符串的长度,n一定要设定,不能省略 - - n <= 4000 - b. CHAR[(n)] - 固定长度的字符型 - - n可以省略,n默认是1 - - n <= 2000 - 3. LOB 型 -- 容纳4GB的数据 - a. 内部lob - CLOB -- 4GB字符型数据 - BLOB -- 4GB二进制数据 - b. 外部lob - BFILE -- 4GB的外部文件 - 4. DATE - 日期型 练习:创建一个 dossier表 dID 数字型 dname 可变长度字符型 30 dheight 数字型 3 dbirthday 日期型 dcountrycode 固定长度字符型,默认值是‘01’ CREATE TABLE dossier ( did NUMBER, dname VARCHAR2(30), dheight NUMBER(3), dbirthday DATE, dcountrycode CHAR(2) DEFAULT '01' ); DROP TABLE dossier INSERT INTO dossier VALUES (1, '姚明', 226, to_date('1980-10-6', 'YYYY-MM-DD'), DEFAULT); COMMIT; INSERT INTO dossier (did, dname, dheight, dbirthday) VALUES (1, '姚明', 226, to_date('1980-10-6', 'YYYY-MM-DD')); SELECT * FROM dossier; - 子查询建表 CREATE TABLE 表名 AS 子查询; CREATE TABLE emp2 AS SELECT * FROM emp WHERE deptno =10; SELECT * FROM emp2; 练习:用20部门员工的姓名和年薪 创建一个新表 annemp20 CREATE TABLE annemp20 AS SELECT ename, (sal + NVL(comm, 0)) * 12 annsal FROM emp WHERE deptno = 20; SELECT * FROM User_Tables; SELECT ROWID, dname FROM dossier; 二. ALTER -- 属于DDL语句,自动提交,不能回滚 -- 修改对象的属性 1. 添加列 ALTER TABLE 表名 ADD (列名 数据类型[,...]); 练习:在dossier表中添加一列 sex 列,1位长度固定长度字符型 ALTER TABLE dossier ADD (sex CHAR); 2. 修改列 ALTER TABLE 表名 MODIFY (列名 属性值); -- 1. 列名一定是在表中存在的列 -- 2. 修改那些属性,就把哪些属性放在列名后面就可以了 练习:为sex列添加默认值,默认为‘1’ ALTER TABLE dossier MODIFY (sex DEFAULT '1'); -- 默认值的修改对表中现有列数据没有任何影响 -- 只会影响以后插入的数据。 -- 将某列更新成其默认值 UPDATE dossier SET sex = DEFAULT WHERE did = 1; 3. 删除列 1> ALTER TABLE 表名 DROP COLUMN 列名; 2> ALTER TABLE 表名 DROP (列名列表); 练习:删除表中sex列 ALTER TABLE dossier DROP (sex); -- 注意:删除列会将列的定义和数据一并删除,不能回滚,在使用之前一定要慎重 -- 必要的时候要现将表中数据备份后再删除。 -- 表中必须至少要含有一列。 三. DROP -- DDL语句,隐式提交不能回滚 -- 删除数据库对象 DROP TABLE 表名; DROP TABLE emp1; 四. 重命名表 RENAME oldname TO NEWname; RENAME dossier TO ouxiang; SELECT * FROM dossier; 五. TRUNCATE TRUNCATE TABLE 表名; -- 截断:删除表中所有的数据; TRUNCATE TABLE emp2; DELETE FROM emp2; -- 两种语句的区别 -- 1. truncate是DDL语句,自动提交,不能回滚,而Delete是DML语句,能回滚; -- 2. truncate在删除数据的同时,会释放存储空间,delete不会做这样的事; -- 3. truncate只能删除所有数据,delete是可以有选择的删除; -- 4. truncate的效率要远远的高于delete,表越大越明显。 回滚段 五. 约束 定义在表中某列上的规则,防止错误数据进入表中; 1. 五种约束 1> NOT NULL :非空约束,插入到该列的数据不能为null; 2> UNIQUE : 唯一键 约束, 该列数据在表中是唯一的,即不能重复; 3> PRIMARY KEY: 主键约束。表中的列或列的组合,其值在表中 可以唯一的确定一条记录; 一个表只能有一个主键。 主键的值必须是非空且唯一的。 在表设计的时候,所有的表必须有主键。 4> FOREIGN KEY : 外键约束。表A和表B的公共字段如果是表A的主键或唯一键的话,那么 就是表B的外键。表A通常成为父表,表B称为子表。 外键是定义在子表上的。 i. 子表的公共字段中不能出现父表中没有的值 UPDATE emp SET deptno = 90 WHERE empno = 7788; ii. 如果父表中的某一个值被子表所引用的话,这条数据不能被删除; DELETE FROM dept WHERE deptno = 10; 5> CHECK :检查约束。在某列上定义的一个boolean表达式,要求插入到该列的值必须要保证 boolean表达式为真,否则无法插入。 2. 约束定义 1> 列级约束定义 CREATE TABLE dossier ( did NUMBER PRIMARY KEY, dname VARCHAR2(30) NOT NULL, dheight NUMBER(3) UNIQUE, dbirthday DATE, dcountrycode CHAR(2) DEFAULT '01' REFERENCES country(countrycode) ); 2> 表级约束定义 CONSTRAINT 约束名 约束类型(列名) CREATE TABLE dossier ( did NUMBER, dname VARCHAR2(30), dheight NUMBER(3), dbirthday DATE NOT NULL, dcountrycode CHAR(2) DEFAULT '01', CONSTRAINT dossier_did_pk PRIMARY KEY(did), CONSTRAINT dossier_dname_uk UNIQUE(dname), CONSTRAINT dossier_dheight_ck CHECK(dheight > 0), CONSTRAINT dossier_countycode_fk FOREIGN KEY(dcountrycode) REFERENCES county(countrycode) ); -- not null只能做列级的约束定义,不能做表级的约束定义 练习:创建一个country表 countrycode 两个字符长度固定字符类型 主键 countryname 非空 CREATE TABLE country ( countrycode CHAR(2), countryname VARCHAR2(30) NOT NULL, CONSTRAINT county_code_pk PRIMARY KEY(countrycode) ); INSERT INTO country VALUES('01', '中国'); SELECT * FROM country; 3> 给现有的表添加约束 ALTER TABLE 表名 ADD [CONSTRAINT 约束名] 约束类型(列名); 练习:给dossier表添加主键约束 ALTER TABLE dossier ADD CONSTRAINT dossier_did_pk PRIMARY KEY(did); 练习:给dossier表的dname列,添加唯一键约束 ALTER TABLE dossier ADD CONSTRAINT dossier_dname_uk UNIQUE(dname); 练习:给dossier表添加check约束,身高不能小于0 ALTER TABLE dossier ADD CONSTRAINT dossier_dheight_ck CHECK(dheight > 0); 练习:给dossier表的生日列添加非空约束 -- ALTER TABLE dossier ADD CONSTRAINT dossier_dbirthday_nn NOT NULL(dbirthday); ALTER TABLE dossier MODIFY (dbirthday NOT NULL); ALTER TABLE dossier ADD CONSTRAINT dossier_dbirthday_ck CHECK (dbirthday IS NO NULL); 练习:给dossier表添加外键约束 ALTER TABLE dossier ADD CONSTRAINT dossier_dcountrycode_fk FOREIGN KEY(dcountrycode) REFERENCES country(countrycode); 4> 删除约束 ALTER TABLE 表名 DROP CONSTRAINT 约束名; 练习:删除dossier表的唯一键约束 ALTER TABLE dossier DROP CONSTRAINT dossier_dname_uk; 练习:删除country表的主键约束 ALTER TABLE country DROP CONSTRAINT county_code_pk CASCADE;
相关文章推荐
- Oracle基础知识(四) - 触发器的基础知识
- hylan:卸载oracle 11g时,关于计算机基础知识的思考:delete和shift+delete的区别
- Oracle、SqlServer——基础知识——oracle 与 SqlServer 的区别(未完工)
- Linux下启动Oracle服务和监听程序(基础知识)
- oracle基础知识(3.2)
- 基础知识:oracle数据字典总结
- Oracle架构的基础知识(入门级)
- Oracle基础知识(4)--SQL组成及Oracle运算符
- oracle 的一些基础知识
- oracle基础知识,oracle sql练习
- oracle基础知识(笔记)
- ORACLE SGA区基础知识与查看命令
- 温故而知新:Oracle基础知识复习(二)
- oracle基础知识
- Oracle基础知识笔记(2)SQLplus命令
- 2. oracle学习入门系列之二 数据库基础知识
- Oracle常用基础知识详解(用户、权限、角色管理 )
- Oracle基础知识(二十四) - select for update
- Oracle基础知识(七) - 序列
- oracle 增量备份恢复策略(基础知识)