oracle 学习(二)

/*
多表查询:
   笛卡尔积:实际上是两张表的乘积
   
   格式:select *from 表1,表2
*/
select *from emp;
select *from dept;

select *from emp e,dept d where e.deptno=d.deptno;
/*
内联结
   隐式内联接
       等值内联接    where e1.deptno=d.deptno;
       不等值内联接:where e.deptno<>d1.deptno;
       自联接:自己联接自己
   显示内联接
       select *from 表1 inner join 表2 连接条件
*/
--查询员工姓名,部门名称,经理的姓名
select e.ename ,d.dname,e2.mgr,e2.ename from  emp e,dept d ,emp e2 
where e.deptno=d.deptno and e.mgr=e2.empno;

--查询员工编号,员工姓名,员工的部门名称,经理的编号,经理的姓名,经理的部门名称
select e1.empno,e1.ename ,d1.dname,e1.mgr,m1.ename,d2.dname 
from emp e1,emp m1,dept d1,dept d2
 where e1.mgr=m1.empno 
and e1.deptno=d1.deptno
and m1.deptno=d2.deptno;
--查询员工编号,员工姓名,员工的部门名称,经理的编号,经理的姓名,经理的部门名称 工资等级
select e1.empno,e1.ename ,d1.dname,e1.mgr,m1.ename,d2.dname ,s1.grade
from emp e1,emp m1,dept d1,dept d2 ,salgrade s1,salgrade s2
 where e1.mgr=m1.empno 
and e1.deptno=d1.deptno
and m1.deptno=d2.deptno
and e1.sal between s1.losal and s1.hisal   
and m1.sal between s2.losal and s2.hisal; //经理的工资等级

--查询员工编号,员工姓名,员工的部门名称,经理的编号,经理的姓名,经理的部门名称 工资等级
--将工资等级显示成中文的一级 二级 三级 ...
select e1.empno,e1.ename ,d1.dname,e1.mgr,m1.ename,d2.dname ,s1.grade
from emp e1,emp m1,dept d1,dept d2 ,salgrade s1,salgrade s2
 where e1.mgr=m1.empno 
and e1.deptno=d1.deptno
and m1.deptno=d2.deptno
and e1.sal between s1.losal and s1.hisal   
and m1.sal between s2.losal and s2.hisal;

select e1.empno,
       e1.ename ,
       d1.dname,
       e1.mgr,
       m1.ename,
       d2.dname ,
      case s1.grade
        when 1 then '一级'
          when 2 then '二级'
            when 3 then '三级'
            when 4 then '四级'
              else '五级'
                 end "等级"
from emp e1,emp m1,dept d1,dept d2 ,salgrade s1,salgrade s2
 where e1.mgr=m1.empno 
and e1.deptno=d1.deptno
and m1.deptno=d2.deptno
and e1.sal between s1.losal and s1.hisal   
and m1.sal between s2.losal and s2.hisal;

--查询员工姓名和员工部门所处的位置
select e1.ename ,d1.dname,d1.loc from emp e1,dept d1 where e1.deptno=d1.deptno;
select *from emp e1 inner join dept d1 on e1.deptno=d1.deptno; 




/*
外连接
   左外连接:left outer join 左表中所有的记录 ,如果右表没有对应记录,就显示空
   又外连接:reght outer join
   outer 关键字可以省略
   
   oracle中外链接:(+)实际上是如果没有对应的记录就加上空值
   select *from emp e1 ,dept d1 where e1.deptno=d1.deptno(+);
*/
select *from emp e1 left outer join dept d1 on e1.deptno=d1.deptno;
select *from emp e1 right outer join dept d1 on e1.deptno=d1.deptno;
insert into emp(empno,ename) values (9527,'huaan');

select *from emp e1 ,dept d1 where e1.deptno=d1.deptno(+);
/*
 子查询:查询语句中嵌套查询语句
     
*/
--查询最高工资的员工信息
select *from emp  where sal=(select max(sal) from emp); 

--查询出比雇员7654的工资高,同时和7788从事相同工作的员工信息
select *from emp where sal>=(select sal from emp where empno='7654') 
and job=(select job from emp where empno='7788') ;

delete from emp where empno='9527';
--查询每个部门最低工资员工信息和他所在的部门的信息
--1.每个部门的最低工资
select deptno, min(sal) from emp group by deptno;
--2.员工工资等于他所处部门的最低工资
select * from emp e , (select deptno, min(sal) minsal from emp group by deptno) t1 where e.deptno=t1.deptno and e.sal=t1.minsal;
--3.查询部门的相关信息
select e1.* ,d1.*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
     通常情况下,数据库中不要出现null,最好的做法加上not null 
     null值并不代表不占空间,char(100) null 100个字符
*/
--查询领导信息
--1.查询所有经理的编号
select 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 where mgr is not null);

--查询出比10号部门任意一个员工工资高的员工信息
select sal from emp where deptno='10';
select * from emp where sal >any(select sal from emp where deptno=10);


--查询出比20号部门所有员工工资高的员工信息
select sal from emp where deptno='20';
select * from emp where sal >all(select sal from emp where deptno='20');

--第二种 
select max(sal) from emp where deptno='20';
select *from emp where sal>(select max(sal) from emp where deptno='20' );

/*
exists(查询语句):存在的意义
    当做布尔值来处理
        当查询语句有结果的时候,就是返回true
           否则返回false
数据量比较大的时候是非常高效的
*/
select *from emp where  exists (select * from emp where deptno=10);

---查询有员工的部门信息
select *from dept d1 where exists(select *from emp e1 where e1.deptno=d1.deptno); 

--找到员工表中工资最高的前三名
select *from emp order by  sal desc;
select rownum ,emp.* from emp  order by  sal desc;
select rownum,t1.* from (select emp.* from emp  order by  sal desc) t1 where rownum<4;  
/*
   rownum : 伪列,系统自动生成的一列,用来表示行号
   是oracle中特有的用来表示行号的,默认值/起始值是1,在每查询出结果之后,在加1
   rownum不能做大于号判断,可以做小于号判断
*/
select rownum,emp.* from emp;

--找到员工表中工资大于本部门平均工资的员工
--1.分组统计部门平均工资
select deptno, avg(sal) from emp group by deptno;
--2.员工工资 > 本部门平均工资
select e1.* from emp e1,(select deptno, avg(sal) avgsal from emp group by deptno) t1 
where e1.deptno=t1.deptno and e1.sal>t1.avgsal;


/*
  关联子查询,非关联子查询
*/
select *from emp e where sal>(select avg(sal) from emp e2 group by deptno having e.deptno=e2.deptno);


/*
统计每年入职的员工个数
*/
select hiredate from emp;
---只显示年
select to_char(hiredate,'yyyy') from emp;
--分组统计
select to_char(hiredate,'yyyy') yy,count(1) cc from emp  group by to_char(hiredate,'yyyy');
--将1980年竖起来
select 
  case yy
    when '1987' then cc end 
from
(select to_char(hiredate,'yyyy') yy,count(1) cc from emp  group by to_char(hiredate,'yyyy')) tt;
--将1980年竖起来,并且取一个别名1980
select 
  case yy
    when '1987' then cc end as "1987"
from
(select to_char(hiredate,'yyyy') yy,count(1) cc from emp  group by to_char(hiredate,'yyyy')) tt;
--去除行记录中的空值
select 
  sum(case yy when '1987' then cc end) as "1987"
from
(select to_char(hiredate,'yyyy') yy,count(1) cc from emp  group by to_char(hiredate,'yyyy')) tt;
--统计员工的总数
select sum(cc) Total
from 
(select to_char(hiredate,'yyyy') yy,count(1) cc from emp  group by to_char(hiredate,'yyyy')) tt;

--将1987和total合并在一起
select 
sum(cc) Total ,
sum(case yy when '1987' then cc end) as "1987"
from
(select to_char(hiredate,'yyyy') yy,count(1) cc from emp  group by to_char(hiredate,'yyyy')) tt;
--显示所有年份的结果
select 
  sum(cc) Total ,
  sum(case yy when '1980' then cc end) as "1980",
  sum(case yy when '1981' then cc end) as "1981",
  sum(case yy when '1982' then cc end) as "1982",
  sum(case yy when '1987' then cc end) as "1987"
from
  (select to_char(hiredate,'yyyy') yy,count(1) cc from emp  group by to_char(hiredate,'yyyy')) tt;

/*
  rowid:伪列,每行记录所存放的真实物理地址
  rownum:行号,每查询出记录之后,就会添加一个行号
*/
select rowid ,e.* from emp e ;

create table p(
 name varchar2(10)
);
insert into p values ('黄飞鸿');
insert into p values ('霍元甲');
insert into p values ('方世玉');
insert into p values ('脾斯麦');

select *from p; 
--去除表中重复记录
select distinct *from p;
select rowid ,p.* from p;
--删除表中重复记录,只保留rowid最小的那行记录
--select min(rowid) from p p2 where p1.name=p2.name; 
delete from p p1   where p1.rowid >(select min(rowid) from p p2 where p1.name=p2.name);


/*
 rownum:分页查询
 在oracle中只能使用子查询进行分页查询
*/
--查询第6-第10 记录
select rownum hhao ,emp.* from emp ;
select *from (select rownum hhao ,emp.* from emp ) tt where tt.hhao between 6 and 10;

/*
集合运算
 并集:将两个查询结果进行合并
 交集
 差集
 
 所有的查询结果可能不是来自同一张表
   
*/
--工资大于1500,或者20号部门下的员工
select *from emp where sal >1500 or deptno=20;
--工资大于1500
select *from emp where sal >1500;
select *from emp where deptno=20;
--并集运算 union ,union all
/*
   union     去除重复,并且排序
   union all 不会去除重复的
*/
--union 去除重复
select *from emp where sal >1500 
union
select *from emp where deptno=20;
--union all
select *from emp where sal >1500 
union all
select *from emp where deptno=20; --12条结果

/*
差集运算:两个结果相减  minus
*/
--查询1981年入职的普通员工(不包括总裁和经理)(差集)
--查询1981年入职的员工
select *from emp where to_char(hiredate,'yyyy')=1981;
--总裁和经理
select *from emp where job='PRESIDENT'or job='MANAGER';
--差集运算
select *from emp where to_char(hiredate,'yyyy')=1981
minus
select *from emp where job='PRESIDENT'or job='MANAGER';


/**
  集合运算中的注意事项:
     1.列的类型要一致
     2.按照顺序写
     3.列的数量要一致  如果不足 可以使用null填充
  
*/
--列的顺序不匹配
select ename ,deptno from emp where sal >1500 
union 
select deptno ,ename from emp where deptno=20; 
--列的数量不匹配 使用null填充  或者类型匹配的其他值填充
select ename ,deptno,'job' from emp where sal >1500 
union 
select  ename ,deptno,job from emp where deptno=20; 

select ename ,deptno,null from emp where sal >1500 
union 
select  ename ,deptno,job from emp where deptno=20; 

猜你喜欢

转载自blog.csdn.net/u011206291/article/details/89762149