Oracle知识点总结(一)

体系结构

数据库-数据库实例-表空间(逻辑单位)(用户)-数据文件(物理单位)

地球-一个国家-省份(逻辑单位)(公民)-山川河流(物理单位)

通常情况下,Oracle数据库只会有一个实例ORCL,

新建一个项目:

     MYSQL : 创建一个数据库,创建相应的表

     Oracle: 创建一个表空间,创建用户,用户去创建表

Oracle和MYSQL的差别

Oracle是多用户的, MYSQL是多数据库的

1. 遵循SQL标准

2. 不同厂商,不同的数据库产品,但是有自己的方言

3. 使用自己的方言,也能够完成相同的功能

4. Oracle安全级别要高,MYSQL开源免费

基本查询:

SQL : 结构化查询语言

请说一下SQL的分类以及每类常见的操作符都有哪些

四类:

DDL : 数据定义语言 create alter drop truncate

DML : 数据操纵语言 insert update delete

DCL : 数据控制语言 安全 授权 grant revoke

DQL : 数据查询语言 select from子句 where子句

查询语句的结构:

 
  

select [列名] [*] from 表名 [where 条件] [group by 分组条件] [having 过滤] [order by 排序]

注意

 
  

select 1+1;  --在Oracle等于报错 ,在MYSQL中输出结果是2

dual : oracle中的虚表 ,伪表, 主要是用来补齐语法结构

 
  

select 1+1 from dual;

select * from dual;

select 1 from emp;

查询表中记录个数

 
  

select count(1from emp;

1代表第一个字段,效率比*高。

 
  

select count(*) from emp; 

别名

别名查询: 使用as 关键字, 可以省略

别名中不能有特殊字符或者关键字, 如果有就加双引号

 
  

select ename 姓名, sal 工资 from emp;

select ename "姓       名", sal 工资 from emp;

去除重复数据 

  • distinct

  • 多列去除重复: 每一列都一样才能够算作是重复 

单列去除重复

 
  

select distinct job from emp;

多列去除重复的

 
  

select distinct job,deptno from emp;

查询中四则运算

 
  

select 1+1 from dual;

查询员工年薪  = 月薪* 12

 
  

select sal*12 from emp;

查询员工年薪+奖金

 
  

select sal*12 + comm from emp; --如果comm中的记录为null,结果不准确

nvl 函数 : 如果参数1为null  就返回参数2

 
  

select sal*12 + nvl(comm,0from emp;

注意: null值 , 代表不确定的 不可预知的内容 , 不可以做四则运算

字符串拼接:

  • java : + 号拼接

  • Oracle 特有的连接符: || 拼接

  • 在Oracle 中 ,双引号主要是别名的时候使用, 单引号是使用的值, 是字符

  • concat(str1,str2) 函数, 在mysql和Oracle中都有

查询员工姓名 :  姓名:SCOTT

 
  

select ename from emp;

使用拼接符

 
  

select '姓名:' || ename from emp;

使用函数拼接

 
  

select concat('姓名:',ename) from emp;

条件查询 : [where后面的写法]   

  • 关系运算符: > >= = < <= != <>

  • 逻辑运算符: and or not

  • 其它运算符:

    • like 模糊查询

    • in(set) 在某个集合内

    • between..and.. 在某个区间内

    • is null  判断为空

    • is not null 判断不为空


查询每月能得到奖金的员工信息

 
  

select * from emp where comm is not null;

查询工资在1500--3000之间的员工信息

 
  
 
   

select * from emp where sal between 1500 and 3000;
select * from emp where sal >= 1500 and sal <= 3000;

查询名字在某个范围的员工信息 ('JONES','SCOTT','FORD') 

 
  

select * from emp where ename in ('JONES','SCOTT','FORD');


匹配单个字符

  • 如果有特殊字符, 需要使用escape转义

  • 模糊查询: like

    • %   匹配多个字符

    •  _单个字符

查询员工姓名第三个字符是O的员工信息

 
  

select * from emp where ename like '__O%';

查询员工姓名中,包含%的员工信息

 
  
 
   

select * from emp where ename like '%\%%' escape '\';

select * from emp where ename like '
%#%%' escape '#';  

排序 : order by 

  • 升序: asc    ascend

  • 降序: desc   descend     

  • 排序注意null问题 :nulls first | last

  • 同时排列多列, 用逗号隔开

查询员工信息,按照奖金由高到低排序

 
  

select * from emp order by comm desc nulls last--nulls last把值为空的放在后面

查询部门编号和按照工资  按照部门升序排序, 工资降序排序

 
  

select deptno, sal from emp order by deptno asc, sal desc;

函数

  • 单行函数: 对某一行中的某个值进行处理

    • 数值函数

    • 字符函数

    • 日期函数

    • 转换函数

    • 通用函数

  • 多行函数: 对某一列的所有行进行处理

    • max() 

    • min()

    • count()

    • sum()

    • avg()

统计员工工资总和

 
  

select sum(sal) from emp; --忽略空值

统计员工奖金总和  2200

 
  

select sum(comm) from emp;

统计员工人数 

 
  

select count(1from emp;

这里用1,也是为了方便,当然如果数据量较大的话,也可以提高速度,因为写count(*)的话会所有列扫描,这里用1的话或者用字段名的话,只扫描你写的那个列其实1就代表你这个查询的表里的第一个字段

统计员工的平均奖金  

 
  

select avg(comm) from emp;  --报错误 ,comm有空值

统计员工的平均奖金 

 
  

select sum(comm)/count(1from emp;

select ceil(sum(comm)/count(1)) from emp;

数值函数

 
  

select ceil(45.926from dual;  --46

select floor(45.926from dual; --45

四舍五入

 
  

select round(45.926,2from dual; --45.93

select round(45.926,1from dual; -- 45.9

select round(45.926,0from dual; --46

select round(45.926,-1from dual; --50

select round(45.926,-2from dual; --0

select round(65.926,-2from dual; --100

截断

 
  

select trunc(45.926,2from dual; --45.92

select trunc(45.926,1from dual; -- 45.9

select trunc(45.926,0from dual; --45

select trunc(45.926,-1from dual; --40

select trunc(45.926,-2from dual; --0

select trunc(65.926,-2from dual; --0

求余

 
  

select mod(9,3from dual; --0

select mod(9,4from dual; --1

字符函数

substr(str1,起始索引,长度) 

 
  

select substr('abcdefg',0,3from dual; --abc

select substr('abcdefg',1,3from dual; --abc

select substr('abcdefg',2,3from dual; --bcd

注意: 起始索引不管写 0 还是 1 都是从第一个字符开始截取

获取字符串长度

 
  

select length('abcdefg'from dual;


去除字符左右两边的空格

 
  

select trim('  hello  'from dual;


替换字符串

 
  

Select replace('hello','l','a'from dual;


取整

 
  

select ceil(-12.5from dual; -12

select floor(12.5from dual; 12


日期函数

  • 查询今天的日期

     
        

    select sysdate from dual;

  • 查询3个月后的今天的日期

     
        

    select add_months(sysdate,3from dual;

  • 查询3天后的日期

     
        

    select sysdate + 3 from dual;

  • 查询员工入职的天数

     
        

    select sysdate - hiredate from  emp;

     
        

    select ceil(sysdate - hiredate) from  emp;

  • 查询员工入职的周数

     
        

    select (sysdate - hiredate)/7 from emp;

  • 查询员工入职的月数

     
        

    select months_between(sysdate,hiredate) from emp;

  • 查询员工入职的年份

     
        

    select months_between(sysdate,hiredate)/12 from emp;


转换函数

字符转数值 

 
  

select 100+'10' from dual;  --110  默认已经帮我们转换

select 100 + to_number('10'from dual; --110

数值转字符

 
  
 
   

select to_char(sal,'$9,999.99'from emp;

select to_char(sal,'L9,999.99'from emp;

to_char(1210.73'9999.9') 返回 '1210.7' 

to_char(1210.73'9,999.99') 返回 '1,210.73' 

to_char(1210.73'$9,999.00') 返回 '$1,210.73' 

to_char(21'000099') 返回 '000021' 

to_char(852,'xxxx') 返回' 354'

日期转字符

 
  

select to_char(sysdate,'yyyy-mm-dd hh:mi:ss'from dual;

select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'from dual;

只想要年

 
  

select to_char(sysdate,'yyyy'from dual;  --2017

只想要日

 
  

select to_char(sysdate,'d'from dual; --2  代表一个星期中第几天

select to_char(sysdate,'dd'from dual;  --10  代表一个月中的第几天

select to_char(sysdate,'ddd'from dual; --100 代表一年中的第几天

当前星期

 
  

select to_char(sysdate,'day'from dual;  --monday

select to_char(sysdate,'dy'from dual;   --mon  星期的简写

字符转日期

 
  

select to_date('2017-04-10','yyyy-mm-dd'from dual;


  • 查询1981年 -- 1985年入职的员工信息

 
  

select * from emp where hiredate between to_date('1981','yyyy'and to_date('1985','yyyy');

通用函数

nvl(参数1,参数2) 如果参数1 = null 就返回参数2

nvl2(参数1,参数2,参数3) 如果参数1 = null ,就返回参数3, 否则返回参数2

nullif(参数1,参数2) 如果参数1 = 参数2 那么就返回 null , 否则返回参数1

coalesce: 返回第一个不为null的值

案例

 
  

select nvl2(null,5,6from dual; --6;

select nvl2(1,5,6from dual; --5;

select nullif(5,6from dual; --5

select nullif(6,6from dual; --null

select coalesce(null,null,3,5,6from dual;  --3

笛卡尔积

两个表的乘积,但是实际开发中没什么意义,利用连接来消除笛卡儿积。

内联接

隐式内联接

  • 等值内联接

 
  

select * from emp e1,dept d1 where e1.deptno = d1.deptno;

  • 不等值内联接

 
  

select * from emp e1,dept d1 where e1.deptno <> d1.deptno;

  • 自连接链接

查询员工编号员工姓名和此员工的经理的编号和姓名

 
  

select e1.empno,e1.ename,e1.mgr,m1.ename from emp e1,emp m1 where e1.mgr = m1.empno;

查询员工编号、员工姓名、部门名称、经理的编号姓名

 
  

select e1.empno,e1.ename,e1.mgr,d1 dname ,m1.ename from emp e1,dept d1 ,emp m1 ,where e1.mgr = m1.empno and e1.deptno = d1.deptno;

显式内联接

 
  

select * from 表1 inner join 表2 on 连接条件

查询员工编号员工姓名和此员工的经理的编号和姓名

 
  

select * from emp e1 inner join dept d1 on e1.deptno = d1.deptno;

外连接

左外连接(Mysql)

左表中所有记录显示出来,如果右表没有对应的记录为空

 
  

select * from emp e1 left outer join dept d1 on e1.deptno = d1.deptno;

右外连接 Mysql)

右表中所有记录显示出来,如果左表没有对应的记录为空

 
  

select * from emp e1 rightouter join dept d1 on e1.deptno = d1.deptno;

Oracle中的外连接(+)

把所有的员工信息打印出来,如果没有对应的部门通过(+)方式添加空值

 
  

select * from emp e1,dept d1 where e1.deptno = d1.deptno(+);

实际上是如果dept没有对应的记录就加上空值

把所有的部门查询出来,如果没有对应的员工就加空值

 
  

select * from emp e1,dept d1 where e1.deptno(+) = d1.deptno;

子查询

查询语句中嵌套查询语句,用来解决类似:“查询最高工资的员工的信息”等复杂的查询语句。

查询最高工资的员工的信息:

1. 查询出最高工资 :5000

 
  

select max(sal) from emp;

2. 工资等于最高工资

 
  

select * from emp where sal = (select max(sal) from emp;);

单行子查询

可以使用> >= = <= <> !=等操作:

查询出比雇员7654的工资高同时和7788从事相同工作的员工信息

1. 雇员7654的工资:1250

 
  

select sal form emp where empno = 7654;

2. 7788从事的工作

 
  

select job from emp where empno = 7788;

3. 两个条件合并(错误,最高工资应该动态获取)

 
  

select * from emp where sal > 1250 and job = 'ANALYST';

3. 两个条件合并(正确,利用子查询)

 
  

select * from emp where sal > (select sal form emp where empno = 7654and job = (select job from emp where empno = 7788);

查询每个部门最低工资的员工信息和他所在部门信息

  1. 查询每个部门最低工资

 
  

select deptno,min(sal) minsal from emp group by deptno;

 2. 查询员工工资=部门最低工资的员工

 
  

- - 两个链接条件,首先是员工表的deptno = 部门表的deptno
- - 并且员工的工资 = 部门表此部门最低工资
select * from emp e1,(select deptno,min(sal) minsal from emp group by deptno) t1 where e1.deptno = t1.deptno and e1.sal = t1.minsal;

 3. 查询员工所在部门相关信息

 
  

select * from emp e1,(select deptno,min(sal) minsal from emp group by deptno) t1 , dept d1 where e1.deptno = t1.deptno and e1.sal = t1.minsal and e1.deptno = d1.deptno;

多行子查询

in、not in、any、all、exists

查询领导信息

1. 查询所有经理的编号

 
  

select mgr from emp;
select distinct mgr from emp;

2. 结果

 
  

select * from emp where empno in (select mgr from emp);

查询不是领导的信息(错误)

 
  

select * from emp where empno not in (select mgr from emp);

上面的SQL是不正确的,因为子查询返回的结果集有null,官方文档表示无论如何都不要在子查询使用 not in,而not in(集合)就相当于<>all(集合)。万一集合中有空值就会报错,因为<>等判断是不能对null操作的。

正确的SQL

 
  

select * from emp where empno not in (select mgr from emp where mgr is not null);

exists(查询语句)

当查询语句有结果时候返回true,否则返回的是false,数据量比较大的时候非常高效。

查询无结果

 
  

select * from emp where exists(select * from emp where deptno = 123456); --- 123456不存在


查询有结果

 
  

select * from emp where exists(select * from emp where deptno = 20); --- 20不存在

查询有员工的部门信息

 
  

select * from dept d1 where exists(select * from emp e1 where e1.deptno = d1.deptno);

查询是一条一条查询的,首先找到需要操作的表dept,dept表的第一条数据的deptno为10,再去执行where条件,拿着deptno为10号的部门记录去emp表依次对比,emp表中如果有deptno为10的数据exists返回true,则把deptno为10的部门表记录打印出来,即此部门有员工信息。


rownum:伪列

系统自动生成的一列,实际上表示行号,默认其实在为1,再查询一条rownum加一。

查询员工表数据,加上行号的一列

 
  

select rownum,e1.* from emp e1;

下方代码查询不到任何记录

 
  

select rownum,e1.* from emp e1 where rowmnum >2;

查询rownum小于6的记录(可以查询到)

 
  

select rownum,e1.* from emp e1 where rowmnum < 6;

rownum不能做大于号判断,可以在小于号判断。

找到员工表中工资最高的前三名

(错误)

 
  

select rownum,e1.* from emp order by sal desc;

上方的代码查询出来的数据是根据sal进行排序的但是,rownum都是乱的,是因为先执行rownum再执行order by。SQL执行顺序为:from .. where .. group by..having ..select ...order by。

找到员工表中工资最高的前三名

(正确)

select e1.* from e1 emp order by sal desc

--把上方查询道德看作一个表查询,rownum不会乱
select rownum,t1.* from(select e1.* from e1 emp order by sal desc) t1;

-- 只要头三条
select rownum,t1.* from(select e1.* from e1 emp order by sal desc) t1 where rownum <= 3;

rowid:每行记录存放的真实的物理地址


推荐阅读


知乎:Web项目聚集地

640

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值