web_day02_多表联查&分页&集合

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35537301/article/details/83685387

一、笛卡儿积

没有实际意义,出现就说明,SQL语句有问题

select * from emp e;  --14
select * from dept d; -- 4

select * from emp e,dept d --56 --笛卡尔积

二、多表查询

1、等值连接/内连接

--范例:查询员工表和部门表
--等值连接/内连接
--隐式
select * from emp e,dept d where e.deptno = d.deptno;
--显式
select * from emp e inner join dept d on e.deptno = d.deptno;

inner join为连接两张表,where为连接两张表和设置过滤条件

2、不等值连接

select * from emp e,dept d where e.deptno<>d.deptno;

3、自连接

--范例:查询出每个员工的上级领导

--隐式内连接
select e1.empno "员工编号",
       e1.ename "员工姓名",
       e2.empno "领导编号",
       e2.ename "领导姓名"
  from emp e1, emp e2
 where e1.mgr = e2.empno;


--显示内连接
select e1.empno "员工编号",
       e1.ename "员工姓名",
       e2.empno "领导编号",
       e2.ename "领导姓名"
  from emp e1
 inner join emp e2
    on e1.mgr = e2.empno;

查询每一个员工的编号,姓名,领导编号,领导姓名,员工的部门名称 

select e1.empno "员工编号",
       e1.ename "员工姓名",
       e2.empno "领导编号",
       e2.ename "领导姓名",
       d.dname  "员工部门名称"
  from emp e1, emp e2, dept d
 where e1.mgr = e2.empno
   and d.deptno = e1.deptno;
   
select e1.empno "员工编号",
       e1.ename "员工姓名",
       e2.empno "领导编号",
       e2.ename "领导姓名",
       d.dname  "员工部门名称"
  from emp e2
 inner join emp e1
    on e2.empno = e1.mgr
 inner join dept d
    on e1.deptno = d.deptno;

查询出每个员工编号,姓名,部门名称,工资等级和他的上级领导的姓名,工资等级 

select e1.empno "员工编号",
        e1.ename "员工姓名",
        e1.deptno "员工部门编号",
        d.dname "员工的部门名称",
        e1.sal "员工工资",
        case s1.grade
          when 1 then '一级'
          when 2 then '二级'
          when 3 then '三级'
          when 4 then '四级'
          else '五级'
        end "员工工资等级",
        e2.empno "领导编号",
        e2.ename "领导姓名",
        e2.sal "领导工资",
        decode(s2.grade,
               1,'一级',
               2,'二级',
               3,'三级',
               4,'四级',
               5,'五级') "领导工资等级"
   from emp e1, emp e2, dept d, salgrade s1, salgrade s2
  where e1.mgr = e2.empno
    and e1.deptno = d.deptno
    and e1.sal between s1.losal and s1.hisal
    and e2.sal between s2.losal and s2.hisal;

 4、外连接

写外连接的时候,需要知道谁是全量表

--范例:查询出所有员工的上级领导

--左外连接(全量表:所有信息保留)
select e1.empno "员工编号",
       e1.ename "员工姓名",
       e2.empno "领导编号",
       e2.ename "领导姓名"
  from emp e1
  left join emp e2
    on e1.mgr = e2.empno;


select e1.empno "员工编号",
       e1.ename "员工姓名",
       e2.empno "领导编号",
       e2.ename "领导姓名"
  from emp e1, emp e2
  where e1.mgr = e2.empno(+); --"+"放在非全量表的那边  

--右外连接   
select e1.empno "员工编号",
       e1.ename "员工姓名",
       e2.empno "领导编号",
       e2.ename "领导姓名"
  from emp e2
  right join emp e1
    on e1.mgr = e2.empno;
  
 
select e1.empno "员工编号",
       e1.ename "员工姓名",
       e2.empno "领导编号",
       e2.ename "领导姓名"
  from emp e1,emp e2
  where e1.mgr = e2.empno(+);

三、子查询

1、单行子查询(子查询结果为单行数据)

1.1 查询比SCOTT工资高的员工

--先查SCOTT的工资
select p.sal from emp p where p.ename = 'SCOTT';

select e.*
  from emp e
 where e.sal > (select p.sal from emp p where p.ename = 'SCOTT');

1.2 查询职位是经理并且工资比7782号员工高的员工 

--先查7782的工资
select p.sal from emp p where p.empno = '7782'

--再设置查询条件
select * from emp e
 where e.job = 'MANAGER'
   and e.sal > (select p.sal from emp p where p.empno = '7782');

 1.3 查询工资最低的员工

--先查最低工资
select min(sal) from emp;

--在设置条件查询
select * from emp e where e.sal=(select min(sal) from emp);

1.3 查询部门最低工资大于30号部门最低工资的结果 

--每个部门的最低工资
select min(sal) from emp group by deptno;

--30号部门的最低工资
select min(e.sal) from emp e where e.deptno=30;


--对分组结果进行过滤
select min(sal), deptno
  from emp
 group by deptno
having min(sal) > (select min(e.sal) from emp e where e.deptno = 30);

 1.4 查询出和SCOTT同部门并且同职位的员工

--查询SCOTT的部门
select e.deptno from emp e where e.ename='SCOTT';

--查询SCOTT的工作
select e.job from emp e where e.ename='SCOTT';

--整合查询条件
select *
  from emp p
 where p.deptno = (select e.deptno from emp e where e.ename = 'SCOTT')
   and p.job = (select e.job from emp e where e.ename = 'SCOTT');

--写成这样的前提是:子查询,查询条件一样   
select *
  from emp e
 where (e.deptno, e.job) =
       (select p.deptno, p.job from emp p where p.ename = 'SCOTT');

 2、多行子查询

2.1 查询每个部门的最低工资和最低工资的雇员和部门名称

--查询每部门的最低工资
select min(sal) x,deptno y from emp group by deptno;

--多行结果,设置成一个表,进行查询
select e.*
  from emp e, (select min(sal) x, deptno y from emp group by deptno) t
 where e.deptno = t.y
   and e.sal = t.x

2.2 查询出不是领导的员工

--查询领导编号
select distinct mgr from emp where mgr is not null;

--在做子查询时需要先去 空值
select *
  from emp e
 where e.empno not in (select distinct mgr from emp where mgr is not null);

2.3 统计员工入职年份

select count(*) 员工个数, to_char(e.hiredate, 'yyyy') "入职年份"
  from emp e
 group by to_char(e.hiredate, 'yyyy');

2.4 行转列

select sum(x) "Total",
       sum(case t.y when '1980' then t.x end) "1980",
       sum(case t.y when '1981' then t.x end) "1981",
       sum(case t.y when '1982' then t.x end) "1982",
       sum(case t.y when '1987' then t.x end) "1987"
  from (select count(*) x, to_char(e.hiredate, 'yyyy') y from emp e group by to_char(e.hiredate, 'yyyy')) t

3、oracle分页

rowid :每行数据的物理地址

rownum:每行数据的序号,序号是随着查询产生的,rownum不能使用>号

oracle数据库,先查询后排序

--显示第一页(1-3)
select t.*, rownum
  from (select * from emp order by sal desc) t
 where rownum < 4;

--显示第二页(4-6)
select *
  from (select t.*, rownum rm from (select * from emp order by sal desc) t) f
 where f.rm < 7
   and f.rm > 3;

--显示第三页(7-9)
select *
  from (select t.*, rownum rm from (select * from emp order by sal desc) t) p
 where p.rm < 10
   and p.rm > 6;

四、集合查询

查询比较复杂的时候用

前提:查询列的数量、列的类型一致,就可以做集合操作

1、并集

查询工资大于1500,或者是20号部门下的员工

1.1 union 去除重复信息

select * from emp e where e.sal>1500
union
select * from emp e where e.deptno='20'

1.2 union 不去除重复信息

select * from emp e where e.sal>1500
union all
select * from emp e where e.deptno='20'

2、交集(intersect)

工资大于1500,并且是20号部门下的员工

select * from emp  e where e.sal >1500
intersect
select * from emp  e where e.deptno=20;

3、补集(minus)

查询1981年入职的普通员工(不包括总裁和经理)

select * from emp e where to_char(e.hiredate,'yyyy')='1981'
minus
select * from emp p  where p.job in ('MANAGER','PRESIDENT');

猜你喜欢

转载自blog.csdn.net/qq_35537301/article/details/83685387