该文章内容不是学习oracle的基础知识,而是在大致了解oracle的基础知识上看我自己还有什么不知道或者不明白的地方,有兴趣的小伙伴可以在网上找找李兴华的oracle培训资料。
SQL 功能强大,概括起来,它可以分成以下几组:
· DML(Data Manipulation Language,数据操作语言) —— 指的是实现数据库的查询与更新操作,其中针对于 数据库的查询有部分人员会将其称为 DQL,因为最麻烦的部分就是查询。
· DDL(Data Definition Language,数据定义语言) —— 定义数据库对象,例如:在一些系统设计人员的工作里 面需要进行数据表的定义。
· DCL(Data Control Language,数据控制语言) —— 控制用户的操作权限,一般由 DBA 负责。
对于重复的数据是有一个基本的原则:只有在所有列的数据都重复的情况下才叫 做重复数据。
SELECT DISTINCT ename,job FROM emp
“||”的连接符,可以进行数据的连接。
SELECT ‘编号:‘ || empno || ‘、姓名:‘ || ename || ‘、工资:‘ || sal info FROM emp
对于 IN 操作而言是针对于基数的判断,如果说此时在使用 NOT IN 的时候基数里面包含了 NULL,那么所有满足
的数据都不会被显示。
范例:观察程序,在 IN 之中使用 NULL —— 现在没有任何的影响
SELECT * FROM emp WHERE empno IN (7369,7566,7839,NULL) ;
范例:观察程序,在 NOT IN 之中使用 NULL
SELECT * FROM emp WHERE empno NOT IN (7369,7566,7839,NULL) ;
不满足的原因是数据库自身的保护机制,避免大数据所带来的问题
字段 LIKE 匹配关键字,而在进行关键字匹配的时候有两个符号标记:
|- “_”:匹配任意一个字符;
|- “%”:匹配 0 个、1 个或多个任意字符。
范例:查询所有姓名第二个字母以 A 开头的所有雇员
SELECT * FROM emp WHERE ename LIKE ‘_A%‘ ;

要查询的数据表名称由用户输入 SELECT * FROM &tablename 利用替代变量输入雇员姓名 SELECT * FROM emp WHERE ename=UPPER(‘&name‘) ;
首字母大写,其余字母小写:字符串 initcap(字符串 | 列)
将每一位雇员姓名的首字母大写,其余字母小写 SELECT INITCAP(ename) FROM emp ;
替换数据列 SELECT ename,REPLACE(ename,‘A‘,‘_‘) FROM emp ;
SELECT SUBSTR(‘hello world‘,0,5) FROM dual ; SELECT SUBSTR(‘hello world‘,1,5) FROM dual ; 以上俩个结果一致,实际上在 Oracle 之中,字符串的索引下标是从 1 开始的(程序是从 0 开始的),但是为了考虑到程序人员的使用习惯, 所以即使设置了 0,那么也表示从 1 开始,这一点会由 Oracle 自己进行处理。
去掉左右空格函数:字符串 TRIM(字符串 | 列)
截取每一位雇员姓名的后三位字母 SELECT ename,SUBSTR(ename,LENGTH(ename)-2) FROM emp ; SELECT ename,SUBSTR(ename,-3) FROM emp ;
SELECT ROUND(9615.7652) , ??9616 ROUND(9615.7652,2), ??9615.77 ROUND(9615.7652,-2), ??9600 ROUND(-15.5) ??-16 FROM dual ;
SELECT ROUND(9615.7652) , ??9615 ROUND(9615.7652,2), ??9615.76 ROUND(9615.7652,-2), ??9600 ROUND(-15.5) ??-15 FROM dual ;
求余数 SELECT MOD(10,3) FROM dual ;
取得当前的系统日期时间,为此在 Oracle 里面提供有两个伪列(是不存在表中的列,但是却可以直接使用的列):SYSDATE、SYSTIMESTAMP
计算每一位雇员到今天为止雇佣的年数 SELECT ename,MONTHS_BETWEEN(SYSDATE,hiredate) , TRUNC(MONTHS_BETWEEN(SYSDATE,hiredate)/12) FROM emp ;
要求计算出每一位雇员到今天为止雇佣的年限(理解) A、 例如:今天是 2014 年 08 月 12 日,CLARK 的雇佣日期是:1981 年 06 月 09 日 B、 到今天 CLARK 已经在公司服务了:33 年、02 月、03 天 SELECT ename,hiredate, TRUNC(MONTHS_BETWEEN(SYSDATE,hiredate)/12) year , TRUNC(MOD(MONTHS_BETWEEN(SYSDATE,hiredate),12)) months , TRUNC(SYSDATE - ADD_MONTHS(hiredate,MONTHS_BETWEEN(SYSDATE,hiredate))) day FROM emp ;
计算下一个星期二 SELECT NEXT_DAY(SYSDATE,‘星期二‘) FROM dual ;
查询出在每个雇员雇佣所在月倒数第二天雇佣的全部雇员信息 SELECT ename,hiredate,LAST_DAY(hiredate)-2 FROM emp WHERE LAST_DAY(hiredate)-2=hiredate ;
拆分日期数据 SELECT TO_CHAR(SYSDATE,‘yyyy‘) year , TO_CHAR(SYSDATE,‘mm‘) months , TO_CHAR(SYSDATE,‘dd‘) day FROM dual ;
转数字类型:数字 TO_NUMBER(字符串,转换格式)
在数据库之中,null 与任何的数据进行数 学计算其结果都是 null,那么如果遇到了 null 应该按照数字 0 来处理,所以就可以使用 NVL()函数。 SELECT ename,sal,comm,(sal+NVL(comm,0))*12 FROM emp ;
将所有雇员的职位数据变为中文 SELECT ename,job , DECODE(job,‘CLERK‘,‘办事员‘,‘SALESMAN‘,‘销售‘,‘MANAGER‘,‘经理‘,‘ANALYST‘,‘分析员‘,‘PRESIDENT‘,‘总裁‘,‘未 处理‘)
将 emp 表(14行数据)和 dept(4行数据) 表实现多表查询 SELECT * FROM emp ,dept ;
执行结果会发现,返回结果有56条数据,为什么呢?出现这样的结果主要是由于数据库的数学公式所导致的,这是两个集合的“积”,而这种积在数据库之中被称为“笛卡尔积”。
如何去消除掉 这样的“笛卡尔积”呢?唯一的方案就是使用关联字段。
不推荐使用的关联方式:
SELECT e.empno,e.ename,e.job,e.sal,d.dname,d.loc FROM emp e , dept d WHERE e.deptno=d.deptno ;
虽然消除掉了显示的笛卡尔积,但是整个运算执行过程非常的缓慢。
对于多表查询来讲其有两种表的连接方式:
SELECT * FROM emp e,dept d WHERE e.deptno=d.deptno(+) ;
SELECT * FROM emp e,dept d WHERE e.deptno(+)=d.deptno ;
SELECT * | 字段 [别名] FROM 表 [CROSS JOIN 表] [NATURAL JOIN 表] [JOIN] [USING(字段)] [ON(条件)] [LEFT | RIGTH | FULL | OUTER JOIN 表] ;
SELECT * | 字段 [别名] FROM 表 CROSS JOIN 表 ;
SELECT * | 字段 [别名] FROM 表 NATURAL JOIN 表 ;
SELECT * | 字段 [别名] FROM 表 JOIN 表 USING(字段);
SELECT * | 字段 [别名] FROM 表 JOIN 表 ON(条件);
SELECT * | 字段 [别名] FROM 表 LEFT | RIGTH | FULL OUTER JOIN 表];
SELECT * FROM emp e LEFT OUTER JOIN dept d ON (e.deptno=d.deptno); SELECT * FROM emp e RIGHT OUTER JOIN dept d ON (e.deptno=d.deptno); SELECT * FROM emp e FULL OUTER JOIN dept d ON (e.deptno=d.deptno);
SELECT [DISTINCT] * | 列名称 [别名] , 列名称 [别名] ,... FROM 数据表 [别名] , 数据表 [别名] ,... [WHERE 条件(s)] [ORDER BY 字段 [ASC | DESC] , 字段 [ASC | DESC] ,...] [UNION | UNION ALL | INTERSECT | MINUS] SELECT [DISTINCT] * | 列名称 [别名] , 列名称 [别名] ,... FROM 数据表 [别名] , 数据表 [别名] ,... [WHERE 条件(s)] [ORDER BY 字段 [ASC | DESC] , 字段 [ASC | DESC] ,...] [UNION | UNION ALL | INTERSECT | MINUS] SELECT [DISTINCT] * | 列名称 [别名] , 列名称 [别名] ,... FROM 数据表 [别名] , 数据表 [别名] ,... [WHERE 条件(s)] [ORDER BY 字段 [ASC | DESC] , 字段 [ASC | DESC] ,...]
统计函数常见的有五个:COUNT()(个数)、SUM()(求和)、AVG()(平均)、MAX()(最大值)、MIN()(最 小值)。
关于统计查询的限制:
![]()


关于 WHERE 和 HAVING 的区别?
SELECT * FROM emp WHERE sal <ANY ( SELECT sal FROM emp WHERE job=‘MANAGER‘)
SELECT * FROM emp WHERE sal <ALL ( SELECT sal FROM emp WHERE job=‘MANAGER‘)
SELECT deptno,AVG(sal) FROM emp GROUP BY deptno HAVING AVG(sal)>( SELECT AVG(sal) FROM emp)
SELECT d.deptno,d.dname,d.loc,temp.count,temp.avg FROM dept d , ( SELECT deptno ,COUNT(empno) count,AVG(sal) avg FROM emp GROUP BY deptno) temp WHERE d.deptno=temp.deptno(+) ;
问题: FROM 子句查询和多表查询有什么差异?emp 表之中存在有 14000 条数据,dept 表中存在有 4000 条数据,查找这两张表会有什么差异呢?
|- 积的数量:emp 的 14000 条 * dept 的 4000 条 = 56,000,000 条数据
|- 第一步(内嵌子查询):针对于 emp 表查询,最多操作 14000 条记录,最多返回 4000 条记录; |- 第二步,子查询和 dept 表关联;
|- 积的数量:dept 表的 4000 条 * 子查询返回的最多 4000 条 = 16000000 条记录; |- 总的数据量:16000000 + 14000 = 16,014,000 条记录
主要目的:子查询的出现主要是为了解决多表查询之中的性能问题
次要目的:很多时候在 FROM 子句里面使用子查询,是因为在外部查询里无法再继续使用统计函数操作的时候
CREATE TABLE myemp AS SELECT * FROM emp ;
# 删除掉那些没有领导的雇员 DELETE FROM myemp WHERE mgr IS NULL ; # 所有员工删除 DELETE FROM myemp;
原文:https://www.cnblogs.com/CSgarcia/p/11434295.html