oracle_sql的用法?

本机连接oracle 数据库?
打开cmd ----> 不同的用户有不同的用户名密码 ----> sqlplus scott/tiger(安装oracle数据库预留的用户)
---- 回车 ---- 提示连接成功…………………………

《基本查询以及过滤查询》
1、oracle sql 优化原则?
  1.尽量使用列名代替*;
  2.where 判断的顺序:右 ----> 左;

  3.理论上,尽量使用多表查询;

  4.尽量不好使用集合运算;

2、mysql 与 oracle 开启事务的区别?
  mysql 开启事务是 start transaction;
  oracle 自动开启事务。

3、什么是sql 与sqlplus?
  sql 是 不可缩写的关键字;
  sqlplus 是可以缩写的。

4、order by 作用于后面所有的列 desc只作用于离他最近的一列
   order by 后面 + 列、表达式、别名、序号
    如:select empno,ename,sal,sal*12 年薪 from emp order by 年薪 desc;
          select empno,ename,sal,sal*12 年薪 from emp order by 4 desc; 根据查询的字段名的顺序,
          若字段名总共有四个,写成第五个则会报错(ORA-01785: ORDER BY 项必须是 SELECT-list 表达式的数目 )。
        select * from emp order by deptno,sal desc; 多个列排序。

5.host cls ---- 清屏

6.展示行宽 ---- show linesize ---- 展示效果linesize 80
  设置行宽 ---- set linesize 120
  设置列宽 ---- col ename for a8 员工姓名这个列是8个字符
  col sal for 9999 一个9代表一个字符

7.sql 中null值问题?
  1.包含null值得表达式都为null;
    如:select * from empno,ename,sal,sal*12,sal*12+nvl(comm,0) from emp;
          sal*12+nvl(comm,0)这一列 comm 为null的值,查出来的结果不正确。
  2.null 永远 != null;
    如:select * from emp where comm=null;
    正确写法:select * from emp where comm is null;
  3.如果集合中含有null,不能使用not in ,但可以使用in。
    如:select * from emp where deptno not in(10,20,null); 运行结果会报 未选定行。
          select * from emp where deptno in(10,20,null);
  4.null 的排序。
    如:select * from emp order by comm asc; 带有null的值的排序,null值显示在最后。
          select * from emp order by comm desc; 降序 null在最上面,有值的在最下面,不符合要求,修改为
      select * from emp order by comm desc nulls last;
      原因:oracle中null值最大。
  5.组合函数(多行函数)自动滤空,可以用嵌套滤空函数来屏蔽他的滤空功能。
    如:select sum(comm)/count(*) 一,sum(comm)/count(comm) 二,avg(comm) 三
      from emp ; count(*) 与 count(comm) 值不相同。
      select sum(comm)/count(*) 一,sum(comm)/count(nvl(comm,0)) 二
      from emp;

8.nvl 表达式?
  nvl(num,0) as "别名" ---- 若num不为null值为num,否则值为0。
  nvl2(a,b,c) 当a=null时候,返回c,否则返回b.
  select sal*12 + nvl2(comm,comm,0) from emp;

9.distinct 去掉重复记录
  distinct作用于后面所有的列
  如:select distinct deptno from emp;

10.日期格式 select * from v$nls_parameters;
  alter session set NLS_DATE_FOTMAT='yyy-mm-dd';
  alter session set NLS_DATE_FORMAT='DD-MON-RR';

11. between and 在什么什么之间
  如:select * from where sal between 1000 and 2000;
  1.含有边界
  2.小值在前,大值在后

12.in(a,b,c) 是a和b和c
  如:select * from emp where deptno not in(10,20)

13.like 模糊查询 %
  如:select * from emp where ename like 'S%'; 查询以S打头的员工。
  select * from emp where ename like '____';查询名字是四个字的员工。
  select * from emp where ename like '%_%';查询名字中含有下划线的员工。


《单行函数》
1.字符函数
  (1)lower()--转小写,upper()--转大写,initcap()--首字母大写
    如:select lower('HELLO WORLD!') 转小写,
    upper('hello')转大写,
    initcap('hello world!')首字母转大写
    from dual;
  (2)substr(a,b) 从a 中第b位开始截取。
    如:select substr('Hello World',3) 子串 from dual;
    结果为:llo World。
  substr(a,b,c) 从a中,第b位开始取,取c位即可。
    如:select substr('Hello World',3,4) 子串 from dual;
    结果:llo 。
  (3)length 字符数 lengthb 字节数
    如:select length('Hello World') 字符,lengthb('Hello World') 字节
      from dual;
      结果:11 11
      select length('北京') 字符,lengthb('北京') 字节 from dual;
      结果:2,4
  (4)inst(a,b) 在a中查找b,找到返回下标,否则返回0。

  (5)lpad()左填充 rpad()右填充
    如:select lpad('abcd',10,'*') 左,rpad('abcd',10,'*') 右 from dual;
    结果:******abcd ,abcd******
  (6)trim() 去掉前后指定的字符
    如:select trim('H' from 'Hello WorldH') from dual;
    结果:ello World
  (7)replace() 替换
    如:select replace('Hello World','l','*') from dual;
    结果:He**o Wor*d
  (8)round() 四舍五入
    如:select round(45.926,2) 一,round(45.926,1) 二,
      round(45.926,0) 三,round(45.926,-1) 四,
      round(45.926,-2) 五
      from dual;
      结果: 45.93 , 45.9 ,46 ,50 ,0
  (9)trunc() 截断
    如:select trunc(45.926,2) 一, trunc(45.926,1) 二,
      trunc(45.926,0) 三,trunc(45.926,-1) 四,
      trunc(45.926,-2) 五 from dual;
2.
(1) 查询当前系统的时间
  select sysdate form dual; 16-7月 -16
(2) 格式化显示时间
  select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;

(3) 昨天、今天、明天
  select (sysdate - 1) 昨天, sysdate 今天,(sysdate+1) 明天 from dual;

(4) 计算员工的工龄:天 星期 月 年
  select ename,hiredate,(sysdate-hiredate) 天,(sysdate-hiredate)/7 星期,
  (sysdate-hiredate)/30 月,(sysdate-hiredate)/365 年
  from emp;
(5)注:日期不允许+日期 ,否则报错。
(6)months_between 相差的月数,是一个准确值
    如:select ename,hiredate,(sysdate-hiredate)/30 近似值,
      months_between(sysdate,hiredate) 准确值
      from emp;
(7)add_months() 向指定的日期上加上相应的月数
    select add_months(sysdate,73) from dual; 当前日期73个月之后。
(8) last_day 月的最后一天
    select last_day(sysdate) from dual;
(9) next_day() 指定的下一个星期几
    select next_day(sysdate,'星期六') from dual; 今天是星期六,下一个星期六就是下周六所在日期。
    select next_day(sysdate,'星期日') from dual; 今天是星期六,下一个星期日就是明天所在的日期。
(10) next_day的应用:每个星期一自动备份表中的数据
  1>分布式数据库
  2>快照
(11) 年月的round 和 trunc
  select round(sysdate,'month'),round(sysdate,'year') from dual;
3.转换函数
显示转换:
  NUMBER -- to_char -- CHARACTER ;
  CHARACTER -- to_number -- NUMBER ;
  CHARACTER -- to_date -- DATE;
  DATE -- to_char -- CHARACTER
(1) 显示:年月日 时分秒 今天是星期几
  select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss"今天是"day') from dual;
(2) 查询员工薪水:俩位小数 千位符 本地货币代码
  select to_char(sal,'L9,999.99') from emp;
  * to_char()函数经常使用的几种格式:
  ** 9 -- 数字
  ** 0 -- 零
  ** $ -- 美元符
  ** L -- 本地货币符号
  ** . -- 小数点
  ** , -- 千位符 意思是每三位加个逗号,

(3) nullif(a,b) 当a=b的时候,返回null,否则返回a。
  select nullif('abc','abc') 值 from dual;

(4) coalesce 从左到右找到第一个不为null的值
  select comm,sal,coalesce(comm,sal) “第一个不为null的值”;

(5) case end:以case开头以end结束, 就是if - then -else
  涨工资,总裁1000 经理800 其他400
    select ename ,job ,sal 涨前,
      case job when 'PERSIDENT' then sal+1000
      when 'MANAGER' then sal+800
      else sal+400
      end 涨后
    from emp;

(6) descode: 和case 实现的功能一样
    select ename,job,sal 涨前,
      decode(job,'PERSIDENT',sal+1000,
      'MANAGER',sal+800,
      sal+400) 涨后
    from emp;


《多行函数》
1.工资总额
  select sum(sal) from emp;

2.人数
  select count(*) from emp;

3.平均工资
  select sum(sal)/count(*) 一,avg(sal) 二 from emp;

4.平均奖金
  select sum(comm)/count(*) 一,sum(comm)/count(comm) 二,avg(comm) 三
  from emp ;
  第一个的平均成绩和后面的俩不一样。原因是:count(*) 和 count(comm) 的值不相同。
  注:null值 组合函数(多行函数)自动滤空,可以用嵌套滤空函数来屏蔽他的滤空功能
  select sum(comm)/count(*) 一,sum(comm)/count(nvl(comm,0)) 二
  from emp;

5.group by 分组。
求每个部门的平均成绩
  select deptno,avg(sal) from emp group by deptno;

6.多个列的分组。
  select deptno,job,sum(sal) from emp group by deptno,job order by 1;
  注:select 列表中所有未包含在组函数中的列都应该包含在group by 子句中;
  包含在group by 子句中的列 不必包含在select 列表中。

7.求部门工资大于2000的部门
  select deptno ,avg(sal) from emp group by deptno having avg(sal) > 2000;
  注:where 后面不能有多行函数(即组合函数)。

8.求10号部门的平均成绩
  select deptno,avg(sal) from emp group by deptno having deptno=10;
  或 select deptno ,avg(sal) from emp where deptno = 10 group by deptno;

《多表查询》
查询数据库有哪些表:select * from tab;
查询表结构:desc 表名

emp 表:
empno,ename,job,mgr(number),hiredate(入职日期),sal(月薪),comm(奖金),
deptno(部门编号)
dept 表:
deptno(部门编号),dname(部门名称),loc
salgrade表:
grade ,losal ,hisal


1.等值连接
查询员工信息 : 员工号 姓名 月薪 部门编号
  select e.empno,e.ename,e.sal,d.dname from emp e,dept d
  where e.deptno = d.deptno;

2.不等值连接
查询员工信息 :员工号 姓名 月薪 工资级别
  select e.empno,e.ename,e.sal,s.grade
  from emp e,salgrade s
  where e.sal between s.losal and s.hisal;
3.外连接

按部门统计员工人数:部门号 部门名称 人数
  select d.deptno 部门编号,d.name 部门名称,count(e.empno) 人数
  from emp e,dept d
  where e.deptno = d.deptno
  group by d.deptno,d.name;

4.希望:对于某些不成立的记录,仍然希望包含在最后的结果中
左外连接:
  当where e.deptno=d.deptno 不成立的时候,等号左边的表仍然被包含在最后的结果中。
  写法:where e.deptno=d.deptno(+)
右外连接:
  当where e.deptno=d.deptno不成立的时候,等号右边的表仍然被包含在最后的结果中。
  写法:where e.deptno(+)=d.deptno
  select d.deptno 部门号,d.dname 部门名称,count(e.empno) 人数
  from emp e,dept d
  where e.deptno(+)=d.deptno
  group by d.deptno,d.dname;

5.自连接
注:通过表的别名,将同一张表视为多张表。自连接不适合操作比较大的表。
查询员工信息 : 员工姓名 员工老板的姓名
  select e.ename 员工姓名,b.ename 老板姓名 from emp e,emp b
  where e.mgr=b.empno;

《子查询》
* 为什么要学习子查询?
** 不能一步求解。

子查询注意的问题:
1.括号
2.合理的书写风格
3.可以在主查询的where select having from 后面都可以防止子查询
4.不可以在group by 后面放置子查询
5.强调from 后面的子查询
6.主查询和子查询可以不是同一张表,只要子查询返回的结果,主查询可以使用即可
7.一般不在子查询中排序,但在top-n分析问题中,必须对子查询排序
8.一般先执行子查询,再执行主查询;但相关子查询例外
9.单行子查询只能使用单行操作符;多行子查询只能使用多行操作符
若子查询返回结果为单行即为单行子查询;若返回结果为多行即为多行子查询
10.子查询中的null值问题

-- 查询工资比SCOTT高的员工
--SCOTT 的工资
  select sal from emp where ename = 'SCOTT'
--比3000高的员工
  select * from emp where sal > 3000

  select * from emp
  where sal > (select sal from emp where ename='SCOTT');

-- 3.可以在主查询的where, select ,having ,from 后面都可以放置子查询
  select empno,ename,sal,(select job from emp where empno=7839) 第四列 from emp;
  select deptno,MIN(sal)
  from emp
  group by deptno
  having MIN(sal) > (select MIN(sal)
  from emp
  where deptno = 10 );
-- 5.强调from 后面的子查询
-- 查询员工信息:员工号 姓名 月薪
  select *
  from (select empno,ename,sal from emp);

-- 查询员工信息:员工号 姓名 月薪 年薪
  select *
  from (select empno,ename,sal,sal*12 annsal from emp);

--6.主查询和子查询可以不是同一张表,只要子查询返回的结果,主查询可以使用即可
-- 查询部门名称是sales的员工
  select *
  from emp
  where deptno=(select deptno from dept where dname='sales');
  或
  select e.*
  from emp e,dept d
  where e.deptno=d.deptno and d.name='sales';
  注:理论上,尽量使用多表查询。
-- 7.一般不在子查询中排序,但在top-n分析问题中,必须对子查询排序
  top-n分析问题:按顺序排序(不论是升序或降序)取前n条,即是top-n分析问题。

-- 8.一般先执行子查询,再执行主查询;但相关子查询例外。
相关子查询:

-- 9.单行子查询只能使用单行操作符;多行子查询只能使用多行操作符
  select ename ,job,sal
  from emp
  where job = (select job from emp where empno=7566)
  and sal > (select sal from emp where empno=7782);
  注:1.单行子查询只能使用单行操作符 = > ……
    2.主查询和子查询的关系是一对多的关系 。
  select ename ,job,sal from emp where sal = (
  select MIN(sal) from emp);

多行操作符:in ,any ,all
  -in :在集合中
  -- 查询部门名称是sales 和 accounting
    select * from emp
    where deptno in (
    select deptno from dept where dname='sales' or d.name='accounting')

    select * from emp ,dept d
    where e.deptno=d.deptno and (dname='sales' or d.name='accounting')

-any 和集合中的任意一个值比较
  -- 查询工资比30号部门任意一个员工高的员工信息
    select * from emp
    where sal > any(select sal from emp where deptno=30);
  或
    where sal > (select min(sal) from emp where deptno=30);

-all 和集合中的所有值比较
-- 查询工资比30号部门所有员工高的员工信息
  select * from emp
  where sal > all(select sal from emp where deptno=30);

-- 多行子查询中的null
-- 查询是老板的员工
  select * from emp
  where empno in (select mgr from emp);

-- 查询不是老板的员工
  select * from emp
  where empno not in(select mgr from emp where mgr is not null);

 

《集合运算》
--查询部门号10和20的员工
1.select * from where deptno in(10,20);
2.select * from where deptno = 10 or deptno = 20;
3.集合运算
select * from emp where deptno = 10;
+
select * from emp where deptno = 20;

注意:集合运算符
1.union/union all 相当于数学中的并集。
  union:若A、B有交集,交集的部分只取一次。
  union all :若A、B有交集,交集的部分取俩次。
注:若A、B无交集,则union 与 union all 是一样的。
  上面的集合运算可替换为:
  select * from emp where deptno = 10;
  union/union all
  select * from emp where deptno = 20;
  注意:1.参与运算的各个集合必须列数相同且类型一致
       2.采用第一个集合作为最后的表头
       3.order by 永远在最后
       4.括号

-- sql 执行时间的开关
打开:set timing on
关闭:set timing off

-- sql前的提示符,显示相应的当前时间。
-- set time on
-- set time off

 

posted on 2016-07-18 22:05  灰灰+灰灰  阅读(671)  评论(0编辑  收藏  举报

导航