数据库划分为关系型数据库和非关系型数据库。
Oracle 数据库系统是目前世界上流行的关系数 据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高 效率、可靠性好的适应高吞吐量的数据库解决方案。
--注释
/*
多行注释
*/
字符串:' '
字符串拼接: ||
查询一张表中的所有数据的所有字段 select * from 数据源;
查询语法 : select 查询的数据(*|字段名|字段1,字段 2...|伪列) from 数据源 别名;
* 一条数据的所有字段值
执行流程: from --> select
--去重 distinct : 对结果集中完全相同的多条数据只显示一条
select distinct deptno from emp;
select 数据 (as) 别名,数据 别名.. from 数据源 别名;
"" 中的内容原封不动显示
如果别名为英文,默认大写,如果想要原封不动显示,前后添加一对""
select ename 员工姓名,sal "empSal",sal*12 as "年 薪" from emp e;
select e.* from emp e;
select 789*654 from dual;
select distinct 789*654 from emp;
1.null值与数字运算,结果为null
2.null值与字符串拼接,结果为原字符串
3.处理null值 : nvl(值1,值2) 当值1为null,nvl函数的结果为值2,当值1不为null,nvl函数的结果为值1
select ename,sal,comm,nvl(comm,0)+1 from emp;
where 过滤行记录条件 ,条件有:
条件查询 : select 要查询的数据 from 数据源 where 行过滤条件 order by 排序字段1,排序字段2...;
执行流程 : from --> where --> select -> order by
条件判断运算符 : = < > <= >= != <>
条件连接符 : and(且) or(或) not(非)
区间判断 : 条件1 and 条件2 | between 值1 and 值2(相当于>=与<=)
any(任意一个) some(任意一个) all(所有)
对结果集进一步操作
union并集去重、 union all并集不去重、 intersect交集 、minus差集
--查询工资大于1500 或 含有佣金的人员姓名
--union 去除重复行
select ename from emp where sal>1500
union
select ename from emp where comm is not null;
-- union all 不去除重复行
select ename from emp where sal>1500
union all
select ename from emp where comm is not null;
--查询显示不存在雇员的所有部门号。
select deptno from dept
minus
select distinct deptno from emp
--查询工资大于1500 且 含有佣金的人员姓名
select ename,sal,comm from emp where sal>1500 intersect
select ename,sal,comm from emp where comm is not null
--查询员工姓名中包含字符A的员工信息
select * from emp where ename like '%A%';
--查询员工姓名中包含第二个A的员工名称信息
select * from emp where ename like '_A%';
--数据中 员工姓名中 存在 _ % ,如何查找:
--1)、编写测试数据
insert into emp(empno,ename,sal) values(1000,'t_%test',8989); insert into
emp(empno,ename,sal) values(1200,'t_tes%t',8000);
--2)、查找
--查询员工姓名中包含字符%的员工名称 岗位 工资 部门编号
select ename,job,sal,deptno from emp where ename like '%a%%' escape('a');
in (值列表) 判断值是否在in后面值列表中,如果在就满足条件,不在不满足
查询工资为1500, 2000, 2500, 5000的员工的信息
SELECT * FROM EMP WHERE SAL=1500 OR SAL=2000 OR SAL=2500 OR SAL=5000;
--in (值列表) 判断值是否在in后面值列表中,如果在就满足条件,不在不满足
select * from emp where sal in(1500,2000,2500,5000);
exists (结果集) 存在即保留,存在即合理
从 from后数据源中拿出每一条数据,判断是否满足where后的条件,如果是exists就判断exists()中的结果集中是否存在数据,存在当前判断的这条数据就满足跳进,不存在就过滤
执行流程 : from --> where --> select --> order by
-- 查询所有员工数据
select * from emp where exists (select * from dept);
-- 查询所有员工数据
select * from emp where exists (select * from emp where comm is not null);
-- 查询10,30部门 的员工信息
select * from emp where exists (select * from dept where deptno in (10,30) and dept.deptno = emp.deptno);
-- 别名
select *
from emp e
where exists (select *
from dept d
where deptno in (10, 30)
and d.deptno = e.deptno);
-- 查询'SALES', 'ACCOUNTING'部门 的员工信息
select *
from emp e
where exists (select deptno, dname
from dept d
where dname in ('SALES', 'ACCOUNTING')
and e.deptno = d.deptno);
-- 查询所有的员工信息
select *
from emp e
where exists (select deptno, dname
from dept d
where dname in ('SALES', 'ACCOUNTING')
and e.deptno != d.deptno);
排序 order by 排序字段1 desc降序|asc升序默认,排序字段2...
对结果集中的数据做排序
-- 查询30部门的员工信息, 并且按工资降序排序
select * from emp where deptno=30 order by sal desc;
子查询 : 查询语句嵌套查询语句
当条件与要查询的数据在不同的数据源,而两个数据源之间存在一定的关联方式,可以子查询中转查询
--部门名称为 SALES 或 ACCOUNTING 的雇员信息
--数据 : 员工信息 *
--来源 : 员工表 emp
--条件 : dname in ('SALES','ACCOUNTING')
--查询 SALES 或 ACCOUNTING的部门编号
select deptno from dept where dname in ('SALES','ACCOUNTING');
--在10,30部门的员工信息
select * from emp where deptno in (10,30) ;
select *
from emp
where deptno in
(select deptno from dept where dname in ('SALES', 'ACCOUNTING'));
-- 查询工资等级为 2的员工信息
--数据 : 员工信息 *
--来源 : 员工表 emp
--条件 : 工资等级为 2
--查询2等级的最低薪与最高薪
select losal from salgrade where grade = 2;
select hisal from salgrade where grade = 2;
--判断员工薪资在这个范围内的员工信息
select * from emp where sal between 1201 and 1400;
select *
from emp
where sal between (select losal from salgrade where grade = 2) and
(select hisal from salgrade where grade = 2);
-- 查询 销售部(SALES) 中 工资大于1500的员工信息
select *
from emp
where deptno = (select deptno from dept where dname = 'SALES')
and sal > 1500;
-- 查询工资比SMITH高的同一部门的员工信息33
select sal from emp where ename='SMITH'
select deptno from emp where ename='SMITH'
select sal
from emp
where sal > (select sal from emp where ename = 'SMITH')
and deptno = (select deptno from emp where ename = 'SMITH');
内置函数
自定义函数
单行函数 : 一条记录返回一个结果
多行函数|组函数|聚合函数 : 多条记录返回一个结果
当前时间:
select sysdate from dual;
select current_date from dual;
-- 日期可以直接+-
-- 2天以后是几号
select sysdate+2 from dual;
-- 所有员工入职的3天后是几号
select ename,hiredate,hiredate+3 from emp;
-- 查询所有员工的试用期期到期(转正的日期) 3个月试用期
select ename,hiredate,hiredate+90 from emp;
select ename,hiredate,add_months(hiredate,-3) from emp;
-- 查询所有员工到目前为止一共工作了几个月
select ename,months_between(sysdate,hiredate) from emp;
-- trunc 取整
select ename,trunc(months_between(sysdate,hiredate)) from emp;
-- 查询当前月的最后一天
select ename,last_day(sysdate) from emp;
-- 下一个星期三是几号
select next_day(sysdate,'星期四') from dual;
--to_char
select sysdate,to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
select sysdate,to_char(sysdate,'yyyy"年"mm"月"dd"日" hh24:mi:ss') from dual;
--to_date
select sysdate,to_date('2022年02月23日','yyyy"年"mm"月"dd"日"') from dual;
nvl(值1,值2) 对null值判断
判定函数 decode(判定字段,值1,结果1,值2,结果2....,默认值) 对判定字段的值进行判定,如果值为值1,函数的结果为结果1,与值2相等,函数的结果为结果2...最终如果以上都不相等,最终取默认值
--给每个部门后后面添加一个伪列,如果10部门,伪列显示为十,二十,三十...
select deptno,dname,loc,decode(deptno,10,'十',20,'二十',30,'三十','无') from dept;
--case when then else end
select deptno,dname,loc,(case deptno when 10 then '十' when 20 then '二十' else '无' end) from dept;
聚合函数
组函数 |聚合函数 | 多行函数 :多条记录返回一个结果
确定要计算的数据然后才能使用组函数,对结果集,分组
count() sum() max() min() avg()
注意: 如果select后面一旦出现组函数的使用,不能与非分组字段一起使用
-- 统计一下一共有多少个员工
select count(*) from emp;
select count(empno) from emp;
select count(deptno) from emp;
select count(1) from emp;
-- 统计一共有几个部门
select count(1) from dept;
-- 统计有员工存在的部门总数
select count(distinct deptno) from emp;
select count(distinct deptno) from emp;
-- 统计20部门一共有多少人
select count(1) from emp where deptno = 20;
-- 计算本公司每个月一共要在工资上花费多少钱
select sum(sal) from emp;
-- 查询本公司的最高工资和最低工资
select max(sal),min(sal) from emp;
--查看30部门的最高工资和最低工资
select max(sal),min(sal) from emp where deptno = 30;
-- 请查询出 20部门的平均工资
select avg(sal) from emp where deptno = 20;
-- 计算出所有员工的奖金总和
select sum(comm) from emp;
--null值不参与组函数计算
-- 统计有奖金的员工有几个
select count(comm) from emp where comm is not null;
--查询最高薪水的员工姓名,及薪水
select max(sal) from emp;
select ename,sal from emp where sal = (最高薪水);
select ename,sal from emp where sal = (select max(sal) from emp);
-- 查询工资低于整个公司平均工资的员工编号,姓名及工资
select empno,ename,sal from emp where sal<(select avg(sal) from emp);
--思考
--查看高于本部门平均薪水员工姓名
select avg(sal) from emp where deptno = 10;
select *
from emp e1
where sal > (select avg(sal) from emp e2 where e2.deptno = e1.deptno);
分组: group by , 将符合条件的记录 进一步的分组
分组 : 根据指定的规则对数据进行分组
group by 分组字段
语法: select 数据 from 数据源 where 行过滤条件 group by 分组 having 组过滤信息 order by 排序字段;
执行流程 : from -> where -> group by -> having -> select -> order by
如果 select后面一旦出现组函数,不能使用非分组字段
如果一旦分组,只能使用分组字段或者组函数
where中不能使用字段别名,不能使用组函数,因为执行流程的问题
1. where : 过滤行记录,不能使用组函数
2. having : 过滤组 可以使用组函数
求出每个部门的平均工资
select deptno,avg(sal) from emp group by deptno;
select deptno,avg(sal) from emp group by deptno;
-- 找出20部门和30部门的最高工资
select deptno,max(sal) from emp group by deptno;
select deptno,max(sal) from emp group by deptno;
--先过滤后分组
select deptno,max(sal) from emp where deptno in(20,30) group by deptno;
select deptno,max(sal) from emp where deptno in(20,30) group by deptno;
--先分组后过滤
select deptno,max(sal) from emp group by deptno having deptno in(20,30);
-- 求出10和20部门部门的哪些工资高于1000的员工的平均工资
select avg(sal) from emp where sal>1000 and deptno in(10,20) group by deptno;
-- 找出每个部门的最高工资
select deptno,max(sal) from emp group by deptno;
-- 求出平均工资高于2000的部门编号和平均工资
select deptno,avg(sal) from emp group by deptno having avg(sal)>2000;
-- 查询最低平均工资的部门编号
--1)找到每个部门的部门编号与平均工资
select deptno,avg(sal) from emp group by deptno;
--2)最低平均工资
select min(avg(sal)) from emp group by deptno;
--3)工资与最低平均工资值相等的部门的部门编号
select deptno,avg(sal) from emp group by deptno having avg(sal)=(最低平均工资);
select deptno
from emp
group by deptno
having avg(sal) = (select min(avg(sal)) from emp group by deptno);
-- 统计每个部门的员工数,和部门编号,按照员工个数升序排序
select deptno,count(1)n from emp group by deptno order by n ;
当我们获取的数据不是来自于同一张表而是来自于多张表时就需要使用到表连接
连表查询92
表连接查询 : 当要查询的数据来自于多个数据源
92 99
92语法 select 数据 from 数据源1,数据源2... where 行过滤条件 group by 分组字段1,分组字段2.. having 组过滤信息 order by 排序字段1,.. desc|asc;
执行流程 : from --> where --> group by --> having --> select --> order by
笛卡尔积 : 交叉连接
--笛卡尔积 : 交叉连接
--查询所有员工的信息以及员工所在部门信息
--数据 : 员工信息* 部门信息*
--来源 : 员工表emp ,部门表 dept
select * from emp,dept;
select emp.*,dept.deptno,dept.dname from emp,dept;
--别名
select e.*,d.deptno,d.dname from emp e,dept d;
--表连接条件 : 过滤通过连表产生的不满足要求的表连接数据
--等值连接 : 判断两个数据源中的某个字段值相等或者不相等
--非等值连接 : 判断区间,判断范围的条件
--92语法中表 连接条件定义 在where后面
--如果要使用的字段来自于多个数据源中都存在,需要指明限定词|出处
select empno,ename,sal,e.deptno,dname from emp e,dept d where e.deptno=d.deptno;
--查询20部门员工的信息以及员工所在部门信息
select empno,ename,sal,e.deptno,dname from emp e,dept d where e.deptno=d.deptno and e.deptno=20;
--非等值连接
--查询每个员工的员工信息以及薪资等级信息
select * from emp e,salgrade s where sal between losal and hisal;
--查询员工信息以及所在部门信息以及薪资等级信息
select *
from emp e, dept d, salgrade s
where e.deptno = d.deptno
and e.sal between s.losal and s.hisal;
--自连接 : 一张表作为两个数据源使用
--查询有上级的员工信息以及上级经理人信息
--数据 : 员工信息 经理人信息
--来源 : 员工表 emp e1 ,经理人表 emp e2
select * from emp e1,emp e2 where e1.mgr=e2.empno;
--内连接 : 满足连接条件查询到不满足过滤掉
--外连接 : 某一个数据源中的数据不满足连接条件的时候也能显示
--左外连接 | 左连接 : from后面主表在左边
--右外连接 | 右连接 : from后面主表在右边
--主表 : 主表中的数据无论是否满足连接条件都能显示
--92语法 : 在连接条件位置,主表的对面添加(+)
--查询所有员工信息以及上级经理人信息
--主表 : 员工表
select * from emp e1,emp e2 where e1.mgr=e2.empno(+);
select * from emp e1,emp e2 where e1.mgr(+)=e2.empno;
--连表查询 99
--笛卡尔积 :
--92
select * from emp,dept;
--99
select * from emp cross join dept;
-- 找出每个员工信息和所在部门信息
--92
select ename,e.deptno,dname from emp e,dept d where e.deptno=d.deptno;
--99
--等值连接
--自然连接 : 自动做等值连接(同名字段|主外键字段) natural join
--注意: 在自然连接中同名字段的不能使用限定词
select ename,deptno,dname from emp natural join dept;
--join ..using(同名字段) 指定使用哪个同名字段做等值连接
select ename,deptno,dname from emp join dept using(deptno);
伪列
rowid行记录的地址,行记录的唯一标识
实现没有主键,唯一字段的表中完全相同数据的去重
--去重
--1)查询到要保留的数据
SELECT DISTINCT ID,NAME,COURSE,SCORE FROM TB_STUDENT; --显示去重
SELECT MAX(ROWID) FROM TB_STUDENT GROUP BY ID,NAME,COURSE,SCORE;
--2)查到要删除的数据
SELECT * FROM TB_STUDENT WHERE NOT ROWID IN (SELECT MAX(ROWID) FROM TB_STUDENT GROUP BY ID,NAME,COURSE,SCORE);
--3)删除这些数据
DELETE FROM TB_STUDENT WHERE NOT ROWID IN (SELECT MAX(ROWID) FROM TB_STUDENT GROUP BY ID,NAME,COURSE,SCORE);
rownum :1、必须排序 2、不能直接取大于 1 的数
rownum : 结果集中行记录的序号
一个结果集就存在一份rownum
--rownum从1开始,每次+1,有规律,有顺序
select deptno,dname,rownum from dept order by deptno desc;
--如果存在排序之后,rownum序号被打乱,可以在select外部再次嵌套select语句,外部的select语句的rownum就是有规律的,可以作为判断使用的
select empno,ename,sal,n,rownum num from (select empno,ename,sal,rownum n from emp order by sal desc);
--在oracle数据库中可以使用rownum实现分页查询
--如果想要对rownum进行判断,需要针对一条已经确定的rownum进行判断,解决方案,外部嵌套select
select empno,ename,sal,n,rownum num from (select empno,ename,sal,rownum n from emp order by sal desc);
--分页 : 每页显示数据个数 n = 3 当前显示第几页 i 起始位置rownum : rownum> (i-1)*n; 结束位置rownum : rownum<=i*n
select *
from (select empno, ename, sal, rownum num
from (select empno, ename, sal, rownum n from emp order by sal desc))
where num <= 6
and num > 3;v