Oracle数据库服务器由一个数据库和至少一个数据库实例组成。 数据库是一组存储数据的文件,而数据库实例则是管理数据库文件的内存结构。此外,数据库是由后台进程组成。
数据库和实例是紧密相连的,所以我们一般说的Oracle数据库,通常指的就是实例和数据库。
下图说明了Oracle数据库服务器体系结构:
在这种体系结构中,Oracle数据库服务器包括两个主要部分:文件(Oracle数据库)和内存(Oracle实例)。
下载地址:
https://www.oracle.com/database/technologies/112010-win64soft.html
https://www.oracle.com/database/technologies/instant-client/downloads.html
都遵循SQL标准,都有自己的方言
EMP(雇员表)
DEPT(部门表)
BOUNS(奖金表)
SALGRADE(工资等级表)
该表是oracle系统提供的一个虚表(伪表),主要用来补齐语法结构,用来构成select的语法规则。
SQL:structured query language 结构查询语言
请说一下SQL的分类,及各类的常用操作符
DDL:数据库定义语言,create、drop、alter、truncate
DML:数据库操作语言,insert、delete、update
DCL:数据库控制语言,grant(授权)、 revoke(回收)
DQL:数据库查询语言,select … from… where… group by… having… order by…limit…
select * from emp;
– as 别名 as可以省略
– 如果别名中有空格等特殊符号,需要把别名使用“”
select ENAME as “雇 员”,HIREDATE “入职时间%” from emp;
– 涉及关键字distinct
–单列去除
select distinct job from emp;
–多列去除,多列都相同才认为重复
select distinct job,deptno from emp;
加减乘除
select 1+1 from dual;
select 1*2 from dual;
select 2/2.5 from dual;
select 2-3 from dual;
案例:获取员工年薪(月薪*12+奖金)
–null值,代表不确定,不可以进行四则运算
select sal*12+comm from emp;
–解决null值问题,nvl(comm,0)
select sal*12+nvl(comm,0) from emp;
使用||进行拼接
–java中使用+拼接
–oracle中使用,||或concat(str1,str2)
–mysql中使用, concat(str,str2)
–oracle中“”主要用来取别名,‘’用来表示字符串
–oracle 中 select “姓名:”||ename from emp,是会报错的
select ename||hiredate from emp;
select 1+1; --oracle报错
select 1+1 from dual; --oracle需要指定dual表
select 1+1; --mysql结果为2
sql查询中where后面的条件
> >= < <= != <>
and or not
select * from emp where comm is not null
select * from emp where sal between 1500 and 3000
select * from emp where sal>=1500 and sal<=3000
select * from emp where ename in (‘ALLEN’,‘JONES’,‘TY’)
select * from emp where ename like ‘__O%’;
update emp set ename=‘ALL_EN’ where ename=‘ALLEN’;
select * from emp where ename like ‘%_%’ escape ‘’;
涉及关键字 order by asc[desc]
asc:升序,默认为升序,desc:降序
注:排序中空值处理,默认为nulls first|last(默认为null值排在最后)
select * from emp order by comm nulls first;
查询员工信息,按照部门编号升序,工资降序
select * from emp order by deptno asc,sal desc;
select 分组条件,分组后的操作 from 表名 group by 分组条件 having 条件过滤
案例:
统计员工平均工资,并查询平均工资大于1500的员工
select empno,avg(sal) from emp group by empno having avg(sal)>1500 ;
注:
SQL编写顺序
Select … from … where … group by … having … order by …
SQL执行顺序
from…where… group by … having … select … order by …
where和having的区别
注:数据库中的函数必须有返回值。
函数分类:单行函数和多行函数
特点:对某一列的所有符合条件的行都进行处理
多行函数也就是我们的聚合函数。聚合函数会忽略空值。
max(), min(), count(), avg(), sum()
select sum(comm) from emp;
select avg(sal) from emp;
–以下查询时错误的,null值影响了
select avg(comm) from emp;
–以下查询才正确
select sum(comm)/count(1) from emp;
特点:对某一行的某个值进行处理
单行函数分类:
select ceil(45.926) from dual; --46
select floor(45.926) from dual; --45
Select abs(-12) from dual; --12
–四舍五入
select round(45.926,2) from dual; --45.93
select round(45.926,1) from dual; --45.9
select round(45.926,0) from dual; --46
select round(45.926,-1) from dual; --50
select round(45.926,-2) from dual; --0
select round(65.926,-2) from dual; --100
–截断
select trunc(45.926,2) from dual; --45.92
select trunc(45.926,1) from dual; --45.9
select trunc(45.926,0) from dual; --45
select trunc(45.926,-1) from dual; --40
select trunc(45.926,-2) from dual; --0
select trunc(65.926,-2) from dual; --0
–取余
select mod(10,2) from dual; --0
select mod(10,3) from dual; --1
select mod(10,3.3) from dual;–0.1
select substr(‘abcdefg’,0,3) from dual; --abc
select substr(‘abcdefg’,1,3) from dual; --abc
select substr(‘abcdefg’,2,3) from dual; --bcd
select length(‘abcdefg’) from dual;
select trim(’ abcdef ') from dual;
select replace(‘ababcccabdd’,‘ab’,‘A’) from dual;–AAcccAdd
select sysdate from dual;
select add_months(sysdate,4) from dual;
select sysdate+3 from dual;
select months_between(sysdate+32,sysdate) from dual;
案例:
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;
to_number(str),其实可以自动转换
select 119+‘110’ from dual; --229
select 119+to_number(‘110’) from dual; --229
to_char(number,’格式’)
select to_char(sal,’$9999,9.99’) from emp;
to_char(date,’格式’)
–to_char(sysdate,‘d’) 每周第几天
select to_char(sysdate,‘d’) from dual;
–to_char(sysdate,‘dd’) 每月第几天
select to_char(sysdate,‘dd’) from dual;
–to_char(sysdate,‘ddd’) 每年第几天
select to_char(sysdate,‘ddd’) from dual;
–to_char(sysdate,‘ww’) 每年第几周
select to_char(sysdate,‘ww’) from dual;
–to_char(sysdate,‘mm’) 每年第几月
select to_char(sysdate,‘mm’) from dual;
–to_char(sysdate,‘q’) 每年第几季
select to_char(sysdate,‘q’) from dual;
–to_char(sysdate,‘yyyy’) 年
select to_char(sysdate,‘yyyy’) from dual;
select to_char(sysdate,‘yyyy-mm-dd hh:mi:ss’) from dual;
select to_date(‘2019/09/02’,‘yyyy/mm/dd’) from dual;
–查询1981年-1985年入职的员工
select * from emp where to_char(emp.hiredate,‘yyyy’)>=1980 and to_char(emp.hiredate,‘yyyy’)<=1985
select * from emp where emp.hiredate between to_date(‘1980’,‘yyyy’) and to_date(‘1985’,‘yyyy’)
【语法】NVL (expr1, expr2)
【功能】若expr1为NULL,返回expr2;expr1不为NULL,返回expr1。
注意两者的类型要一致
select nvl(null,‘s2’) from dual;
select nvl(‘s1’,‘s2’) from dual;
【语法】NVL2 (expr1, expr2, expr3)
【功能】expr1不为NULL,返回expr2;
expr1为NULL,返回expr3。
expr2和expr3类型不同的话,expr3会转换为expr2的类型
select nvl2(null,‘s1’,‘s2’) from dual; --s2
select nvl2(‘s0’,‘s1’,‘s2’) from dual; --s1
【语法】NULLIF (expr1, expr2)
【功能】expr1和expr2相等返回NULL,不相等返回expr1
select nullif(‘s1’,‘s2’) from dual; --s1
select nullif(‘s1’,‘s1’) from dual; --null
select nullif(3,3) from dual; -null
【语法】COALESCE(c1, c2, …,cn)
【功能】返回列表中第一个非空的表达式,如果所有表达式都为空值则返回1个空值
【参数】c1, c2, …,cn,字符型/数值型/日期型,必须类型相同或null
select coalesce(2,3) from dual;
select coalesce(’’,‘aa’,‘bb’) from dual;
select
case ename
when ‘SCOTT’ then ‘考斯特’
when ‘SMITH’ then ‘斯密斯’
else ‘路人’
end
from emp;
select decode(ename,‘SMITH’,‘斯密斯’,‘SCOTT’,‘考斯特’,‘路人’) from emp;
没有where条件的交叉连接将产生连接表所涉及的笛卡尔积。即table_a的行数*table_b的行数的结果集。
注:结果没有实际意义
select a.,b. from a inner join b on a.id=b.id
select a.,b. from a,b where a.id=b.id
案例:
查询员工的编号、姓名、部门名称
select e.empno,e.ename,t.dname from emp e join dept t on e.deptno=t.deptno;
不等值连接查询就是无条件判断,若查询多个表内的数据,其中的数据不会同步,各自把各自的展现出来,没有任何关联。笛卡儿积数据除了等值连接后的数据。
自连接的连接的两种表是同一张表
案例:
查询拥有上司的员工的编号、姓名、上司编号、上司姓名
select * from emp e1 ,emp e2 where e1.mgr=e2.empno
查询拥有上司的员工的编号、姓名、员工部门名称、员工工资等级、上司编号、上司姓名、上司部门名称
–查询拥有上司的员工的编号、姓名、员工部门名称、员工工资等级、上司编号、上司姓名、上司部门名称
–1.查询拥有上司的员工的编号、姓名、上司编号、上司姓名
select e.ename,e.empno,e.mgr from emp e,emp e2 where e.mgr=e2.empno;
–2.给符合的员工找部门
select e.ename,e.empno,e.mgr,d1.dname from emp e,emp e2,dept d1 where e.mgr=e2.empno and e.deptno=d1.deptno
–3.给上司找部门
select e.ename,e.empno,e.mgr, d1.dname “员工部门”,e2.ename “上司名称”,d2.dname “上司部门” from emp e,emp e2,dept d1,dept d2 where e.mgr=e2.empno and e.deptno=d1.deptno and e2.deptno=d2.deptno
–4.获取员工工资等级,还需进行连表,和工资表进行连接
select e.ename,
e.empno,
e.mgr,
s.grade “员工工资等级”,
d1.dname “员工部门”,
e2.ename “上司名称”,
d2.dname “上司部门”
from emp e, emp e2, dept d1, dept d2,salgrade s
where e.mgr = e2.empno
and e.deptno = d1.deptno
and e2.deptno = d2.deptno
and e.sal>=s.losal and e.sal<=s.hisal;
left outer join
查询数据:左表中的所有数据, 如果右表中没有对应的数据则置为空 outer 关键字可以省略
案例:
查询员工编号,及其上司的编号,上司名称
select * from emp e1 left join emp e2 on e1.mgr= e2.empno
right outer join
查询数据:右表中的所有数据, 如果左表中没有对应的数据则置为空outer 关键字可以省略
select * from emp e1 right join dept d on e1.deptno=d.deptno
子查询是一个嵌套在 SELECT、INSERT、UPDATE 或 DELETE 语句或其他子查询中的查询,子查询(内查询)在主查询之前一次执行完成,子查询的结果被主查询(外查询)使用,子查询要包含在括号内,将子查询放在比较条件的右侧,多行操作符对应多行子查询。
子查询作用:
1)可以作为另一个查询的条件
2)可以作为一张表
子查询注意的问题:
案例:
查询员工中最高工资的人员信息
–查询员工中最高工资的人员信息
–1.查询最高工资
select max(sal) from emp;
–2.查询工资为5000的员工信息
select * from emp where sal=(select max(sal) from emp);
查询每个部门最低员工的信息和它所在部门的信息
–1.查询各个部门最低工资
select deptno,min(sal) minsal from emp group by deptno;
–2.查询各个部门最低工资的员工
select e.* from emp e ,
(select deptno,min(sal) minsal from emp group by deptno) t
where e.deptno=t.deptno and e.sal=t.minsal
–3.查询各个部门最低工资的员工信息和部门信息
select e.*,d.dname,d.loc from emp e ,
(select deptno,min(sal) minsal from emp group by deptno) t,dept d
where e.deptno=e.deptno and e.sal=t.minsal and e.deptno=d.deptno
将子查询和比较运算符联合使用,必须保证子查询返回的值不能多于一个
案例:
查询出比雇员7654工资高,同时和7788从事相同工作的员工信息
select * from emp where sal>(select sal from emp where empno=7654) and job = (select job from emp where empno=7788)
多行子查询,子查询的结果是多行,选择的比较运算符要使用多行比较运算符。
案例:
https://blog.csdn.net/weixin_44545511/article/details/89080333
查询领导信息
select * from emp where empno in(select distinct mgr from emp where mgr is not null);
查询比任意领导编号小的员工信息
select * from emp where empno
查询比所有领导编号大的员工信息
select * from emp where empno >all (select distinct mgr from emp where mgr is not null);
exists子查找如果有数据,则进行主查询
exists子查询无数据,则不进行
案例:
查询有员工的部门信息
–查询有员工的部门信息
select * from dept where deptno in (select distinct deptno from emp )
select d.* from dept d where exists (select empno from emp e where e.deptno=d.deptno );
rownum:oracle的关键字,表示伪列,系统自动生成的一列,用来标识行号。是Oracle中特有的,启始值为1,查询出一条记录,值增1。
数据库查询数据,是一条一条查询,而不是一次性都查询出来。
select e.,rownum from emp e where rownum>2; --查询不出数据,默认rownum值1,不符合条件查询不出数据
select e.,rownum from emp e where rownum>=1; --查询出所有数据
select e.*,rownum from emp e where rownum<=3; --查询前三条数据
总结:rownum不用做大于运算。
rowid表示每行记录的物理地址。
案例:
create table p(
name nvarchar2(50)
);
insert into p values (‘阿狗’);
select * from p;
去除重复列
delete from p p1 where p1.rowid>(select min(rowid) from p p2 where p1.name=p2.name )
将两个查询结果进行合并。关键字为union/union all
union:合并会去重,并且会根据第一个字段进行排序
union all:只合并不去重
案例:
工资大于1500,或者20号部门下的员工
select * from emp where sal>1500 or deptno=20
select * from emp where sal>1500 union select * from emp where deptno=20
–由于我们的数据可能来自不同的表,如果是不同表第一种就查询不正确了
将两边的查询结果进行交集运算。关键字为intersect
案例:
工资大于1500,且在20号部门下的员工
select * from emp where sal>1500 intersect select * from emp where deptno=20
返回第一个查询结果,且不属于第二个查询的结果。关键字minus
案例:
查询1981年入职的,且不是总裁和经理的员工信息
–查询1981年入职的,且不是总裁和经理的员工信息
–1.查询1981年入职的
select * from emp where to_char(hiredate,‘yyyy’)=1981
minus
–2.查询1981年入职的总裁和经理
select * from emp where (job=‘PRESIDENT’ or job =‘MANAGER’) and to_char(hiredate,‘yyyy’)=1981
–查询1981年入职的,且不是总裁和经理的员工信息
–1.查询1981年入职的
select deptno,ename,null from emp where to_char(hiredate,‘yyyy’)=1981
minus
–2.查询1981年入职的总裁和经理
select deptno,ename,empno from emp where (job=‘PRESIDENT’ or job =‘MANAGER’) and to_char(hiredate,‘yyyy’)=1981