— 基本查询
— 查询所有的雇员
select * from emp ;
— 查询别名
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp;
— 别名 :后面的中文用双引号,一般的别名都不用中文
select empno “员工编号”,ename as “员工姓名” ,job as “工作” from emp;
— 四则运算
— 查询员工的年薪:空值是oracle里面最大的
select ename , sal* 12 from emp ;
select ename , sal* 12+comm from emp ;
–nvl函数,判断空值用的 第一个参是值,第二参数:如果第一个参数是null,那么就用第二个参数来替换
select ename,sal*12+nvl(comm,0) from emp;
— 条件与排序查询
— 查询
— 语法: select * from 表名 where 条件 order by 字段 asc|desc
— 查询薪资大于1500
select * from emp where sal > 1500;
— 查询薪资大于1000,并且有奖金的员工
select * from emp where sal > 1000 and comm >0 and comm is not null;
select * from emp where sal > 1000 and comm is not null and comm >0;
— 查询薪资大于等于1500 并且小于等于3000
select * from emp where sal >=1500 and sal <= 3000;
— 范围查询: between xx and XXX; 包括边界值
select * from emp where sal between 1500 and 3000;
— in操作 :在某个数据内
select * from emp where empno in(7369,7788);
— 模糊查询 like
— 查询名字中有个M 字符的
select * from emp where ename like ‘%M%’;
— 查询名字中第二个字母是M 字符的
select * from emp where ename like ‘_M%’;
— 排序
/*
语法:
select *
from tabs
where condition…
order by 字段1 asc |desc nulls first|last,字段2 asc |desc
— 工资从小到大排列
select *
from emp
where sal > 1000
order by sal asc;
— 工资从大到小排列
select *
from emp
where sal > 1000
order by sal desc;
— 查询员工,把奖金从小到大排列
select *
from emp
where sal > 1000
order by comm asc;
— 查询员工,把奖金从大到小排列
select *
from emp
where sal > 1000
order by comm desc nulls last;
— 单行函数
/*
dual : 是oracle提供给我们的一张伪表,它用于补全sql语法
/
— 字符串操作
— 大小写
select upper(‘abc’) from dual;
select lower(‘ABC’) from dual;
— 查询用户名称小写的
select empno,lower(ename) from emp;
— 字符串拼接
— concat(第一个参数,第二个参数),只能有两个参数
select concat(concat(‘hello’,’johnny’),’hao are you’) from dual;
— 字符串的拼接建议使用 || , 相当于java语言 + 号
select ‘hello’||’johnny’||’hao are you’ from dual;
— 字符串长度
select length(‘123456’) from dual;
— 截取字符串
/
substr(v1,p1,p2)
v1:要截取的字符串
p1: 从哪里开始截取,0 和 1 都是一样的,都是开始下标
p2: 截取的长度
*/
select substr(‘hello’,0,2) from dual;
select substr(‘hello’,1,2) from dual;
select substr(‘hello’,2,2) from dual;
— 数值函数
–操作数字
— 四舍五入
select round(50.8) from dual;–只保留整数位
select round(50.883888,2) from dual;– 第二个参数,保留两位小数
— 截断
select trunc(50.88888,2) from dual;– 直接截断
— 日期操作
— sysdate : 当前数据库所在服务器的时间
select sysdate from dual;
— 查询员工入职的天数
select round(sysdate-hiredate) from emp;
— 在上面的基础上,算一下入职的周数
select round((sysdate-hiredate)/7) from emp;
— 计算入职的月数
select ename,hiredate, round(months_between(sysdate,hiredate)) from emp;
— 转换函数
— 把时间转成字符串
select to_char(sysdate,’yyyy-mm-dd’) from dual;
— 把字符串转成时间
select to_date(‘2018-09-05′,’yyyy-mm-dd’) from dual;
— 把数字转成字符
select to_char(123) from dual;
— 把字符串转成数字
select to_number(‘123’) from dual;
— 空值判断
— nvl(p1,p2) ,如果p1为空,就输出p2,前后的数据类型要一直
select ename,nvl(comm,0) from emp;
— 条件表达式
/*
if (){
}else if(){
}else{
}
*/
select ename,deptno from emp;
select ename,deptno,
decode(deptno ,’10’,’java部门’,’20’,’UI部门’,’30’,’测试部门’ ,’大boss’)
from emp;
— 使用 case when
select ename,
case deptno
when 10 then ‘java部门’
when 20 then ‘UI部门’
when 30 then ‘测试部门’
else ‘大boss’
end
from emp;
— 多行函数
/*
聚合查询:在where条件中不能写聚合函数,只能写在 having 中
svg()
count()
max()
min()
sum()
/
— 计算所有员工
select count() from emp;
— 把所有员工的工资加起来
select sum(sal) from emp;
— 计算部门的平均工资
select deptno,avg(sal)
from emp
group by deptno;
— 计算部门的平均工资大于2000
select deptno,avg(sal)
from emp
group by deptno
having avg(sal) > 2000;
/*
完整的sql语法:
select *
from 表名
where 条件
group by 分组
having 条件
order by 排序
*/
— 内连接
— 练习1: 查询出雇员的编号,姓名,部门的编号和名称,地址
select e.empno ,e.ename,d.deptno,d.dname,d.loc
from emp e, dept d
where e.deptno = d.deptno ;
— 练习2: 在上面的基础上,查询出员工领导的名称和编号
select e.empno ,e.ename,d.deptno,d.dname,d.loc,m.ename,m.empno
from emp e, dept d ,emp m
where e.deptno = d.deptno
and e.mgr=m.empno;
— 练习3: 在上面的基础上,查询领导的部门的名称和编号
select e.empno ,e.ename,d.deptno,d.dname,d.loc,m.ename,m.empno ,p.dname,p.deptno
from emp e, dept d ,emp m ,dept p
where e.deptno = d.deptno
and e.mgr=m.empno
and p.deptno = d.deptno ;
— 练习4: 在上面的基础上,查询出员工的薪资级别
select e.empno ,e.ename,d.deptno,d.dname,d.loc,m.ename,m.empno ,p.dname,p.deptno,s.grade as “薪资级别”
from emp e, dept d ,emp m ,dept p ,salgrade s
where e.deptno = d.deptno
and e.mgr=m.empno
and p.deptno = d.deptno
and e.sal between s.losal and s.hisal;
— 练习5: 在上面的基础上,把员工的薪资级别把阿拉伯数字改成中文 “一”
select e.empno ,e.ename,d.deptno,d.dname,d.loc,m.ename,m.empno ,p.dname,p.deptno
,decode(s.grade,1,’一’,2,’二’,3,’三’,4,’四’,5,’五’)
from emp e, dept d ,emp m ,dept p ,salgrade s
where e.deptno = d.deptno
and e.mgr=m.empno
and p.deptno = d.deptno
and e.sal between s.losal and s.hisal;
— 外链接
/*
外链接查询: 判断以哪种表为基准表,如果是基准表,那么他的数据全部显示
左连接: select * from tab1 left join tab2 on 条件 — tab1 基准表 全部显示
右连接: select * from tab1 right join tab2 on 条件 — tab2 基准表 全部显示
*/
— 左连接
select * from dept d left join emp e on d.deptno = e.deptno ;
— 右连接
select * from dept d right join emp e on e.deptno = d.deptno ;
— Oracle:特有的外链接
select *
from emp e,dept d
where e.deptno(+) = d.deptno;
— 子查询
— 查询与scott薪资一样的员工
select sal from emp where ename=’SCOTT’;
select * from emp where sal = (select sal from emp where ename=’SCOTT’);
–练习: 查询薪资与7654 员工一样的员工 ,或者 工作与 7788 员工的工作一样
select * from emp where empno = 7654 ;
select * from emp where empno = 7788 ;
select * from emp
where sal=( select sal from emp where empno = 7654 )
or
job = ( select job from emp where empno = 7788);
— 要求查询每个部门的最低工资和最低工资的雇员和部门名称
— 1找出每个部门的最低工资
select deptno ,min(sal)
from emp
group by deptno ;
— 2找出最低工资的雇员
select * from
emp e , ( select deptno ,min(sal) as dminsal
from emp
group by deptno) t
where e.deptno = t.deptno
and e.sal = t.dminsal;
— 3找出部门名称
select * from
emp e , ( select deptno ,min(sal) as dminsal
from emp
group by deptno) t ,
dept d
where e.deptno = t.deptno
and e.sal = t.dminsal
and d.deptno = e.deptno;
— 空值问题 不会报错
select * from emp
where job =
(select job from emp where ename =’Mike’ );
— 子查询-Exists用法
select * from emp where 1 = 1 ;
— 相当于 (true)
select * from emp where exists (select * from emp where ename=’SCOTT’);
select * from emp where 1=2;
— 相当于 (flase)
select * from emp where exists (select * from emp where ename=’S’);
— 查询拥有员工的部门
select *
from dept d
where exists(select * from emp e where d.deptno = e.deptno ) ;
— 使用in替换
select *
from dept d
where d.deptno in (select distinct deptno from emp ) ;
— 如果是大数据量【百万级】的查询 建议使用exists(找到马上就返回) 使用in会全表查询
–练习1: 找到员工表中工资最高的额前三名
/*
rownum ,rowid :伪例
oracle提供的两例
rownum:数据查询出来之后,分配一个序号
rowid:指向数据储存的物理地址
/
select rownum , e.,rowid from emp e; –不是真实存在于这张表的
select * from emp where rowid =’AAAMfPAAEAAAAAgAAC’;
— 排序
select * from emp worder by sal desc ;
— 条件
select * from emp where rownum<4 order by sal desc ; — 不能使用
— 排序好的表作为一张表进行查询
select rownum , t.* from ( select * from emp order by sal desc ) t
where rownum<4 ;
— 优化
select rownum ,t.empno,t.ename,t.sal
from ( select * from emp order by sal desc ) t
where rownum<4 ;
–练习2:找到员工中薪水大于本部门平均薪水的员工
— 找到部门的平均薪水
select deptno , avg(sal) as davgsal
from emp
group by deptno ;
— 条件
select e.empno , e.ename,e.sal,d.davgsal
from emp e , ( select deptno , avg(sal) as davgsal
from emp
group by deptno) d
where e.deptno = d.deptno
and e.sal > d.davgsal ;
–练习3: 统计每年入职的员工个数
— 把入职日期先更换成年
select to_char(sysdate,’yyyy’) from dual ;
select to_char(hiredate , ‘yyyy’) from emp ;
— 上次结果作为一张表进行查询
select e.hireyear ,count(hireyear)
from (select to_char(hiredate , ‘yyyy’) as hireyear from emp ) e
group by e.hireyear ;
— 优化 (了解)
select sum(hirecount) as total,
–使用聚合函数补全语法 别名都用双引号
avg(decode (hireyear,’1980′,hirecount)) as “1980” ,
avg(decode (hireyear,’1981′,hirecount)) as “1981” ,
avg(decode (hireyear,’1982′,hirecount)) as “1982” ,
avg(decode (hireyear,’1987′,hirecount)) as “1987”
from (select e.hireyear ,count(hireyear) as hirecount
from (select to_char(hiredate , ‘yyyy’) as hireyear from emp ) e
group by e.hireyear ) t ;
— 分页处理 (rownum实现)
select rownum , e.* from emp e ;
— 找出第一页数据,每页三条
select rownum , e.* from emp e
where rownum<4;
— 找出第二页数据,每页三条 错误演示
— 注意:不能使用大于符号
— 原因:找出一条数据分配一个rownum
select rownum , e.* from emp e
where rownum>3 ;
— 找出第二页数据,每页三条
select rownum , e.* from emp e ;
— 先查出rownum作为一张表去查询
select * from
(select rownum as XX , e.* from emp e) t
where xx <7 and xx > 3 ;
/*
mysql分页:
limit startIndex,pageSize
Oracle分页:
select * from
(select rownum as XX , e.* from emp e) t
where xx <maxResult and xx > startIndex ;
startIndex = (currentPage-1)*pageSize
maxResult = (currentPage-1)pageSize+pageSize
*/
— 练习: 对员工表的工资排序【降序】后,取出第二页,每页三条数据
select *
from emp
order by sal desc ;
— 作为一张表进行查询
select rownum as XXX , e2.* from ( select rownum as XX , e.*
from emp e
order by sal desc ) e2;
— 再次作为一张表
select e3.* from (select rownum as XXX , e2.* from
( select e.*
from emp e
order by sal desc ) e2 )e3
where e3.XXX>3 and e3.XXX<7;
— 集合运算(了解)
— 并集: 工资大于1500或者20号部门下的员工
select *
from emp
where sal > 1500 or deptno = 20 ;
— 使用 or关键字效率低,全表查询 ,索引使用不了
— 使用union all会产生重复的数据 不会去除重复
select * from emp where sal > 1500 union all
select * from emp where deptno = 20 ;
— 使用union 会去除重复数据
select * from emp where sal > 1500 union
select * from emp where deptno = 20 ;
— 交集:工资大于1500并且是20号部门下的员工
select *
from emp
where sal > 1500 and deptno = 20 ;
— 使用intersect
select * from emp where sal > 1500 intersect
select * from emp where deptno = 20 ;
— 差集: 1981年入职的员工不包括总裁和经理
select * from emp where to_char(hiredate,’yyyy’)=’1981′
minus
select * from emp where job = ‘MANAGER’ or job = ‘PRESIDENT’;