数据库的一些操作(二)

03-子查询:
--部门名称为 SALES 或 ACCOUNTING 的雇员信息
--查询的数据: 员工信息*
--来源: emp
--条件: 部门名称=SALES 或 ACCOUNTING
--1)先查询出部门名称=SALES 或 ACCOUNTING对应的部门编号
select deptno from dept where dname in('SALES','ACCOUNTING');

--子查询
select *
  from emp
 where deptno in
       (select deptno from dept where dname in ('SALES', 'ACCOUNTING'));

-- 查询工资等级为 2的员工信息
select * from emp;
select * from salgrade;
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的员工信息
--查询的数据: 员工信息*
--来源: emp
--条件: 部门名称=SALES and sal>1500
select *
  from emp
 where sal > 1500
   and deptno = (select deptno from dept where dname = 'SALES');

select *
  from (select *
          from emp
         where deptno = (select deptno from dept where dname = 'SALES'))
 where sal > 1500;

-- 查询工资比SMITH高的同一部门的员工信息
--查询的数据: 员工信息*
--来源: emp
--条件: sal>SMITH的薪资  and deptno = SMITH的部门编号
select *
  from emp
 where sal > (select sal from emp where ename = 'SMITH')
   and deptno = (select deptno from emp where ename = 'SMITH');

--exists 存在即保留,存在即合法
select *
  from emp
 where exists (select deptno from dept where dname = 'SALES');

select *
  from emp
 where exists (select deptno
          from dept
         where dname in ('SALES', 'ACCOUNTING')
            and emp.deptno =dept.deptno);
            
--别名

select *
  from emp e
 where exists (select deptno
          from dept d
         where dname in ('SALES', 'ACCOUNTING')
            and e.deptno =d.deptno);
            
--20部门的员工信息
select *
  from emp e
 where not exists (select deptno
          from dept d
         where dname in ('SALES', 'ACCOUNTING')
            and e.deptno = d.deptno);
            
            
--有奖金的员工信息
select empno, ename, sal,comm
  from emp e1
 where exists (select empno, ename, sal, comm
          from emp e2
         where comm is not null
           and e1.empno = e2.empno);
    
--与有奖金的员工统一部门的所有员工的员工信息     
select empno, ename, sal,deptno
  from emp e1
 where exists (select empno, ename, sal, comm,deptno
          from emp e2
         where comm is not null
           and e1.deptno = e2.deptno);```

04函数
--单行函数:一条数据返回一个结果
--多行函数|组函数|聚合函数:多条数据返回一个结果

-- 当前时间
select sysdate from dual;
select current_date from dual;
select ename,sysdate from emp;

-- 加减日期
-- 2天以后是几号
select sysdate+2 from dual;

-- 所有员工入职的3天前是几号
select ename,hiredate,hiredate-3 from emp;


-- 查询所有员工的试用期期到期(转正的日期) 3个月试用期
select ename,hiredate 入职日期,hiredate+30*3 转正日期 from emp;
--add_months() 月份相加
select ename,hiredate 入职日期,add_months(hiredate,3) 转正日期 from emp;

-- 查询所有员工到目前为止一共工作了几个月
select ename,months_between(sysdate,hiredate) from emp;

-- 查询当前月的最后一天
select last_day(sysdate) from dual;
select last_day(hiredate) from emp;

-- 下一个星期三是几号
select next_day(sysdate,'星期一') from dual;

--日期对象与字符串之间的转问题
-- to_date('字符串','识别日期字符串模板')
-- 设定一个特定的时间(用一个特定的时间字符串转换为日期)
select to_date('2019-07-30 10:11:13','yyyy-mm-dd hh24:mi:ss')+3 from dual;
select to_date('2019年07月30日 10:11:13','yyyy"年"mm"月"dd"日" hh24:mi:ss') from dual;

-- 将日期转为特定格式的字符串 to_char()
select to_char(sysdate,'yyyy"年"mm"月"dd"日" hh24:mi:ss') from dual;


-- decode 判断decode(判定字段,校验字段值1,结果1,校验字段2,结果2。。,默认值)
--给每个部门后后面添加一个伪列,如果10部门,伪列显示为十,二十,三十...
select deptno,dname,decode(deptno,10,'十',20,'二十',30,'三十',40,'四十') 中文名字 from dept;

-- 给20部门的所有员工都涨薪10%,显示出员工的名称, 原来的薪水, 所属部门编号, 涨薪后的薪水
select ename,sal 原薪水,deptno 部门编号,decode(deptno,20,sal*1.1,sal) 涨薪后的薪水 from emp;



-- 10部门涨薪10%, 20涨薪20%,30降薪1% , 40部门翻倍3倍
select  ename,sal 原薪水,deptno 部门编号,case deptno(when 10 then sal*1.1,when 20 then sal*1.2,when 30 then sal*1.01,end sal) from emp;

-- 组函数: count() sum() max() min() avg()
--对确定的结果集使用函数得结果
--注意: select后 组函数不能和非组函数或分组字段一起使用
--注意: where 不能使用组函数

-- 统计一下一共有多少个员工
--count(*|1|字段)
select 1 from emp;
select count(1) from emp;

-- 统计一共有几个部门 
select count(*) from dept;

-- 统计有员工存在的部门总数
select distinct deptno from emp;
select count(distinct deptno) from emp;
select count(distinct 1) from emp;

-- 统计20部门一共有多少人
select count(1) from emp where deptno=20;

--sum()
-- 计算本公司每个月一共要在工资上花费多少钱
select sum(sal) from emp;

-- 计算20部门每个月的工资花销
select sum(sal) from emp where deptno = 20;

--max()  min()
-- 查询本公司的最高工资和最低工资
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;


--null值不参与运算
-- 计算出所有员工的奖金总和
select sum(comm) from emp;
select sum(comm) from emp where comm is not null;

-- 统计有奖金的员工有几个
select count(1) from emp where comm is not null;

--查询 最高薪水的员工姓名,及薪水
select max(sal) from emp;
select ename, sal from emp where sal = (select max(sal) from emp);

-- 查询工资低于平均工资的员工编号,姓名及工资


--查看 高于本部门平均薪水员工姓名
select ename from emp e1 where exists ( select ename from emp e2 where(sal>(select avg(sal) from emp) and e1.deptno=e2.deptno))
--查询82年入职的员工信息
select * from emp where hiredate like '%82%';
select * from emp where  to_char(hiredate,'yyyy')='1982';

--分组
--select 数据 from 数据源 where 行过滤条件 group by 分组字段 having 组过滤信息 order by 排序字段;
--执行顺序: from --where--group by--having--select--order by

--所有有员工存在的部门编号
select distinct deptno from emp;

select deptno from emp group by deptno;

--10,30,部门的每个部门最高薪资
select max(sal)  from emp group by deptno;
--先过滤再分组
select max(sal) from emp where deptno in(10,30) group by deptno ;
--先分组再过滤
select max(sal),deptno  from emp group by deptno having deptno in(10,30);

--如果有分组,select后只能跟分组字段和组函数

-- 求出平均工资高于2000的部门编号和平均工资
select deptno,avg(sal) from emp group by deptno having avg(sal)>2000;
--按 部门岗位(job) 查询 平均工资
select job,avg(sal) from emp group by  job;
--按 岗位查询 平均工资,且平均工资大于2000的岗位
select job,avg(sal) from emp group by job having avg(sal)>2000; 
--求平均薪资最高的部门编号
select avg(sal),deptno from emp group by deptno having ;
--求没个部门的平均薪资
select deptno,avg(sal) from emp group by deptno;
--求最高部门的平均薪资
--select max(select avg(sal) from emp group by deptno) from emp; 

--where 行过滤 having 组过滤
--from--where--group by --having --
select * from emp where sal>() ;

create table tb_student(
id number(4) ,
name varchar2(20),
course varchar2(20),
score number(5,2)
);
insert into tb_student values(1,'张三','语文',81);
insert into tb_student values(2,'张三','数学',75);
insert into tb_student values(3,'李四','语文',81);
insert into tb_student values(4,'李四','数学',90);
insert into tb_student values(5,'王五','语文',81);
insert into tb_student values(6,'王五','数学',100);
insert into tb_student values(7,'王五','英语',90);
commit;
drop table tb_student cascade constraints;

select * from tb_student;

--使用一条sql语句,查询出没门课程分数都>80分的学生名字
--查询的数据: 学生名字 name
--数据的来源: tb_student
--条件: 没门分数都要>80 and 每一个人的总课程数=3
select name
  from tb_student
 group by name
having min(score) > 80 and count(1) = (select count(distinct course)
                                         from tb_student);
---------------
select name,score from tb_student group by name having score>80 and (select count(distinct course) from tb_student);                                         
--每个人如果最分数都>80,证明所有成绩都>80
select name from tb_student group by name having min(score)>80;
-----------------
select name from tb_student group by name having min(score)>80;

--一共有几门课程
select count(distinct course) from tb_student;
select name from tb_student group by name having count(1) =3;
----------
select count(distinct course) from tb_student;
select name,count(course) "已考试科目" from tb_student group by name;

--行转列
select name,
       min(decode(course, '语文', score)) "语文",
       max(decode(course, '数学', score)) "数学",
       avg(nvl(decode(course, '英语', score),0)) "英文"
  from tb_student
 group by name;
 -----练习
 select name,min(decode(course,'语文',score)) "语文",max(decode(course,'数学',score)) "数学",max(nvl(decode(course,'英语',score),0)) "英语"from tb_student group by name;
--rowid和rownum都是伪列
--rowid相当于表中每一个条记录的地址,数据插入到表中的时候就已经存在,后续不会改变
select empno,ename,rowid from emp;

--去重,没有主键,没有唯一的字段,可以存在多条数据重复,想要达到去重,可以使用rowid


insert into tb_student values(1,'张三','语文',81);
insert into tb_student values(2,'张三','数学',75);
insert into tb_student values(3,'李四','语文',81);
insert into tb_student values(4,'李四','数学',90);
insert into tb_student values(5,'王五','语文',81);

select * from tb_student;

--查到唯一的不重复的每一条数据,重复的数据只显示一条
select name,course,score,min(rowid) from tb_student group by name,course,score;

select *  from tb_student where rowid in (select min(rowid)
                                            from tb_student
                                           group by name, course, score);

--查询要删除的数据
select *  from tb_student where not rowid in (select min(rowid)
                                            from tb_student
                                           group by name, course, score);

--删除这些数据
delete from tb_student
 where not rowid in
        (select min(rowid) from tb_student group by name, course, score);
        
--rownum结果集中数据的序号
select empno,ename,sal,rownum from emp order by sal;
select deptno,dname,rownum from dept;


--分页查询
select empno,ename,sal,rownum from emp where rownum<=5;
--rownum不确定,因为结果集不确定
select empno,ename,sal,rownum from emp where rownum>=6 and rownum<=10;
--如果结果集能确定,对以确定的rownum进行判断,肯定能够判断
select empno,ename,sal,rownum,n from (select empno,ename,sal,rownum n from emp) where n>=6 and n<=10;

--一页显示4条数据 num=4,显示也是  i 
-- i=1  起始数据的rownum=1  结束:rownum=4
-- i=2  起始数据的rownum=5  结束:rownum=8
-- i=3  起始数据的rownum=(i-1)*num+1=9  结束:rownum=i*num=12

--根据薪资进行升序排序,达到分页的效果一页显示4条数据 num=4,显示第二页的数据i=2

select empno,ename,sal,rownum n from emp order by sal; 
--对已经确定的数据,按照执行的要求排序后的,rownum已经确定的,有规律的,从1开始,每次+1
select empno,ename,sal,rownum n from (select empno,ename,sal,rownum from emp order by sal); 

--分页
select empno, ename, sal,n
  from (select empno, ename, sal, rownum n
          from (select empno, ename, sal, rownum from emp order by sal))
 where n >= 5
   and n <= 8;
--查询每一个员工的员工信息,以及所在的部门信息
--数据: 员工信息,部门信息
--来源:emp,dept
--连表查询
--92,99语法

--92语法
--笛卡尔积
select * from emp,dept order by sal;

--等值连接  可以是两个表中的相同字段做连接,可以是不同字段做连接,但是类型要保持一致
select * from emp,dept where emp.deptno=dept.deptno;
select * from emp,dept where emp.ename=dept.dname;

--非等值连接
--查询每个员工的信息以及这个员工的薪资等级
select * from emp,salgrade where sal between losal and hisal;

--查询2500薪资的等级
select grade from salgrade where 2500 between losal and hisal;

--查询 每一个的员工的员工信息,薪资等级,部门信息
select * from emp,dept,salgrade where emp.deptno=dept.deptno and sal between losal and hisal;
--查询 30部门员工的 每一个的员工的员工信息,薪资等级,部门信息

--92语法中,相同的字段一定要指明字段的出处
select *
  from emp, dept, salgrade
 where dept.deptno = 30
   and emp.deptno = dept.deptno
   and sal between losal and hisal;

--30部门的员工信息及部门信息
--先连接后过滤
select empno,ename,e.deptno,dname from emp e,dept d where e.deptno=d.deptno and e.deptno=30;
--先过滤后连接,效率较高
select empno, ename, e.deptno, dname
  from (select * from emp where deptno = 30) e,
       (select * from dept where deptno = 30) d;
       
--查询所有有上级的员工信息及其上级经理人信息  自连接
--员工表 e1和经理人表 e2
select * from emp e1,emp e2 where e1.mgr=e2.empno;

--查询所有的员工信息及其上级经理人信息 所有员工都应该显示
--想要无论是否满足连接条件,都要显示其中数据的表->主表

--外链接
--做为主表的表中的数据全部显示
--在连接条件的位置,在主表对面的表的连接条件后添加(+)
-- emp e1,emp e2 主表的位置确定,主表在左边叫做左连接,主表在右边,叫做右连接
select * from emp e1,emp e2 where e1.mgr=e2.empno(+); --左连接
select * from emp e2,emp e1 where e1.mgr=e2.empno(+); --右连接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值