为了账号安全,请及时绑定邮箱和手机立即绑定

Oracle高级查询

  • 外连接

    核心:通过外连接,把对于连接条件不成立的记录,仍然包含在最后的结果中

    左外连接:当连接条件不成立的时候,等号左边的表仍然被包含

    右外连接:当连接条件不成立的时候,等号右边的表仍然被包含

    注意:左右外连接的叫法和写法是相反的。如:若是右外连接,则在等号的左边加上(+)符合,左外连接则在等号的右边加上(+)符号。

    select d.deptno,d.dname,count(e.empno) from emp e,dept d where e.deptno(+)=d.deptno group by d.deptno,d.dname;

    查看全部
    0 采集 收起 来源:[Oracle] 外连接

    2019-05-27

  • 分组函数 avg min max
    查看全部
  • 分组函数不忽略空值
    查看全部
    0 采集 收起 来源:使用分组函数3

    2019-05-20

  • --#案例三:按部门统计员工人数(已知员工入职年份)

    select count(*) from emp;

    select HIREDATE from emp;

    select count(*) Total,

           sum(decode(to_char(hiredate,'YYYY'),'1981',1,0)) "1981",

           sum(decode(to_char(hiredate,'YYYY'),'1980',1,0)) "1980",

           sum(decode(to_char(hiredate,'YYYY'),'1982',1,0)) "1982",

           sum(decode(to_char(hiredate,'YYYY'),'1987',1,0)) "1987"

    from emp;--函数方式

    -------------------------

    select 

    (select count(*) from emp) Total,

    (select count(*) from emp where to_char(hiredate,'yyyy')='1980') "1980",

    (select count(*) from emp where to_char(hiredate,'yyyy')='1981') "1981",

    (select count(*) from emp where to_char(hiredate,'yyyy')='1982') "1982",

    (select count(*) from emp where to_char(hiredate,'yyyy')='1987') "1987"

    from dual;--子查询方式


    ----------

    --创建表

    desc pn_ci;

    desc PM_STU;

    create table pn_ci

    (CI_ID varchar2(20) NOT NULL,

     STU_IDS  varchar2(100));--选课表

    -------------------

    create table pm_stu

    (STU_ID varchar2(20) NOT NULL,

     STU_NAME  varchar2(20));--学生表

    ------------------

    INSERT into pn_ci values('1','1,2,3,4');

    INSERT into pn_ci values('2','14');

    select * from pn_ci;

    ---------------------

    INSERT into pm_stu values('1','张三');

    INSERT into pm_stu values('2','李四');

    INSERT into pm_stu values('3','王五');

    INSERT into pm_stu values('4','赵六');

    select * from pm_stu;

    https://img1.sycdn.imooc.com//5cdbdc9b0001befd05250175.jpg


    查看全部
    0 采集 收起 来源:练习

    2019-05-15

  • --#案例三:按部门统计员工人数(已知员工入职年份)

    select count(*) from emp;

    select HIREDATE from emp;

    select count(*) Total,

           sum(decode(to_char(hiredate,'YYYY'),'1981',1,0)) "1981",

           sum(decode(to_char(hiredate,'YYYY'),'1980',1,0)) "1980",

           sum(decode(to_char(hiredate,'YYYY'),'1982',1,0)) "1982",

           sum(decode(to_char(hiredate,'YYYY'),'1987',1,0)) "1987"

    from emp;--函数方式

    -------------------------

    select 

    (select count(*) from emp) Total,

    (select count(*) from emp where to_char(hiredate,'yyyy')='1980') "1980",

    (select count(*) from emp where to_char(hiredate,'yyyy')='1981') "1981",

    (select count(*) from emp where to_char(hiredate,'yyyy')='1982') "1982",

    (select count(*) from emp where to_char(hiredate,'yyyy')='1987') "1987"

    from dual;--子查询方式


    ----------

    --创建表

    desc pn_ci;

    desc PM_STU;

    create table pn_ci

    (CI_ID varchar2(20) NOT NULL,

     STU_IDS  varchar2(100));--选课表

    -------------------

    create table pm_stu

    (STU_ID varchar2(20) NOT NULL,

     STU_NAME  varchar2(20));--学生表

    ------------------

    INSERT into pn_ci values('1','1,2,3,4');

    INSERT into pn_ci values('2','14');

    select * from pn_ci;

    ---------------------

    INSERT into pm_stu values('1','张三');

    INSERT into pm_stu values('2','李四');

    INSERT into pm_stu values('3','王五');

    INSERT into pm_stu values('4','赵六');

    select * from pm_stu;

    https://img1.sycdn.imooc.com//5cdbdc9b0001befd05250175.jpg


    查看全部
    0 采集 收起 来源:练习

    2019-05-15

  • 设置报表样式

    查看全部
  • 第五章 :解决实际问题

    案例一:分页查询显示员工信息:显示员工号,姓名,月薪

    --每页显示四条记录

    --显示第二页的员工

    --按照月薪降序排列

    select empno,ename,sal from emp order by sal desc;

    --rownum 行号(永远从1开始),只能使用<,<=,不能使用>,>=

    select r,empno,ename,sal

    from (select rownum r,empno,ename,sal 

       from (select rownum,empno,ename,sal from emp order by sal desc) e1

     where rownum<=8) e2

     where r>=5;--r是e2表的第一列,变成不是伪列的值

    案例2:找到员工表中薪水大于本部门平均薪水的员工

    select * from emp ;

    --部门平均薪水

    select deptno,avg(sal) from emp  group by deptno;

    ----------------------------------------------------------

    explain plan for

    select empno,ename,sal,(select avg(sal) from emp where deptno=e.deptno) avgsal

    from emp e

    where sal>(select avg(sal) from emp where deptno=e.deptno);

    select * from table (dbms_xplan.display);

    ----------------------------------------------------------

    explain plan for--解释计划

    select * 

    from emp e ,(select deptno,avg(sal) avgsal from emp  group by deptno) d

    where e.deptno=d.deptno and e.sal>d.avgsal;--多表查询,嵌套子查询

    --查看执行计划

    select * from table (dbms_xplan.display);--占用CPU更少


    查看全部
    0 采集 收起 来源:本章概述

    2019-05-15

  • 简单的报表实现,统计部门工资,并作出总和

    break on  deptno  skip 2   将相同的部门号不显示,并且跳过两行预留空白

    查看全部
  • group  by  语句增强  例子

    查看全部
  • group by 语句增强

    查看全部
  • 使用列转行listagg函数https://img1.sycdn.imooc.com//5cc66a5b00018b4713320199.jpg

    查看全部
    0 采集 收起 来源:练习

    2019-04-29

  • 第四章:子查询

    1.子查询案例

    示例:查询工资比员工scott高的员工信息

    select * from emp 

    where sal>(select sal from emp where ename='SCOTT');

    2.子查询注意的10个问题

    • 子查询语法中的小括号

    • 子查询的书写风格

    • 可以使用子查询的位置:where,select,having,from

    select empno,ename,sal,(select job from emp where empno=7839) 第四列

    from emp ;

    select deptno,avg(sal) from emp group by deptno

    having avg(sal)>(select max(sal) from emp where deptno=30);--having与where区别,having可以跟group by,where不可以。

    • 不可以使用子查询的位置:group by

    --按照部门查询部门平均工资

    select deptno,avg(sal) from emp group by deptno;--正确

    select deptno,avg(sal) from 

    emp group by (select deptno from emp);--错误

    • 强调:from后面的子查询

    --from后面的子查询,看做新的表

    --示例1:查询员工信息:员工号,姓名,月薪

    select empno,ename,sal from emp;

    --示例1:查询员工信息:员工号,姓名,月薪,年薪

    select empno,ename,sal,(select sal*12 from emp) from emp;

    select empno,ename,sal 月薪,sal*12 年薪 from emp;

    select * from (select empno,ename,sal 月薪,sal*12 年薪 from emp);

    • 主查询和子查询可以不是同一张表

    --主查询和子查询可以不是同一张表

    --示例:查询部门名称是SALES的员工信息

    select * from dept;

    select * from emp 

      where deptno=

      (select deptno from DEPT where dname='SALES');


    select e.* from emp e,dept d

      where e.deptno=d.deptno 

      and d.dname='SALES';

      --结果一致,理论上,下面的好与上面的,实际中,子查询好于多表查询,因为笛卡尔集很大

    • 一般不在子查询中,使用排序;但在Top-N分析问题中,必须对子查询排序

    --一般不在子查询中进行排序

    --Top-N分析中要排序

    --示例:找到员工表中工资最高的前三名

    --rownum 行号 伪列  (查询语句中必须写出它)

    --行号需要注意的两个问题:行号永远按照默认顺序生成,行号只能使用<.<=;不能使用>,>=

    select rownum,empno,ename,sal from

    (select * from emp order by sal desc)

    where rownum<=3;--正确排序

    select  rownum,empno,ename,sal from emp  

    where rownum<=3

    order by sal desc;

    --只是前三条记录,没有按照薪水排序

    • 一般先执行子查询,再执行主查询,但相关子查询例外

    --示例:找到员工表中薪水大于本部门平均薪水的员工

    select empno,ename,sal,(select avg(sal) from emp where deptno=e.deptno) avgsal 

    from emp e 

    where sal>(select avg(sal) from emp where deptno=e.deptno);

    • 单行子查询只能使用单行操作符(查询语句返回一条记录);

      多行子查询只能使用多行操作符(查询语句返回多条记录)

    --子查询只返回一条记录叫单行子查询,返回两条及以上记录叫多行操作符

    --单行子查询只能使用单行操作符,多行子查询只能使用多行操作符

    --单行操作符:=,>,>=,<,<=,<>;多行操作符:in,any,all

    --查询员工信息,要求:职位与7566员工一样,薪水大于7782员工的薪水

    select * from emp 

    where job=(select job from emp where empno=7566) --单行子查询,

    and sal>(select sal from emp where empno=7782);

    --单行子查询只能使用单行操作符,一个查询语句中可以有多个单行子查询

    --单行子查询

    --查询工资最低的员工信息

    select * from emp 

    where sal in (select min(sal) from emp); 

    select * from emp 

    where sal = (select min(sal) from emp); --单行子查询

    --查询最低工资,大于10号部门最低工资,的部门号和部门的最低工资

    select deptno,min(sal) from emp group by deptno;--所有部门的最低工资

    (select min(sal) from emp where deptno=20) ;--10号部门最低工资

    select * from (select deptno,min(sal) b  from emp group by deptno) 

    where b>(select min(sal) from emp where deptno=20);--不使用having

    select deptno,min(sal) from emp group by deptno

    having min(sal)>(select min(sal) from emp where deptno=20) ;

    --分组函数后面不能跟where,可以跟having代替where

    --非法使用单行子查询

    select empno,ename from emp

    where sal = (select min(sal) from emp group by deptno);--子查询中是多行的集合,非法

    --多行操作符in

    --查询部门名称是SALES和ACCOUNTING的员工

    select emp.* from emp,dept where emp.DEPTNO=dept.DEPTNO --多表查询

    and dept.dname IN('SALES','ACCOUNTING');

    select emp.* from emp,dept where emp.DEPTNO=dept.DEPTNO --多表查询

    and (dept.dname  ='SALES' or dept.dname ='ACCOUNTING');--优先级先and,后or

    select * from emp --子查询

    where deptno in 

    (select deptno from dept where dname ='SALES' or dname ='ACCOUNTING');

    --多行操作符ANY

    --查询工资比30号部门任意一个员工高的员工信息

    select * from emp where sal>(select min(sal) from emp where deptno=30);

    select * from emp where sal >any(select sal from emp where deptno=30);

    --多行操作符ALL

    select * from emp where sal >ALL(select sal from emp where deptno=30);

    • 注意:子查询中是null值问题

    --单行子查询中的null值问题,判断一个值等不等与null值不能用=或<>,因为永远是不等的,

    --判断一个值等不等与null值,只能用IN 或is not

    select * from emp 

      where job=

      (select job from emp where ename='TOM');--子查询不返回任何行

    --多行子查询中的空值

    --查询不是老板的员工

    select * from emp where empno  in (select MGR from emp);

    select * from emp where empno not in (select MGR from emp);--空值

    --只要子查询中返回值包含null值,不要使用not in,因为not in 等同与<> ALL(不等于所有值)

    select * from emp 

    where empno not in 

      (select MGR from emp where mgr is not null);--加上不为空的限制



    查看全部
  • 第三章:多表连接

     1. 多表查询

     多表查询:从多个表中获取数据

     查询员工信息与部门信息,员工表与部门表

     2. 笛卡尔集

     多表查询的基础

    表1*表2的笛卡尔集:列数=两张表相加,行数两张表相乘

    连接条件N-1个,N代表多少张表连接

    https://img1.sycdn.imooc.com//5cc565620001e43e08180317.jpg

     3. 等值连接

      等值连接:连接条件中是等号

      示例:查询员工信息,要求显示:员工号,姓名,月薪,部门名称

      试验:select empno,ename,sal,dname from emp 

                 left join DEPT on emp.deptno=dept.deptno;

       标准:select e.empno,e.ename,e.sal,d.dname

                    from emp e,dept d where e.deptno=d.deptno;

                 (习惯上重命名表)

     4. 不等值连接

         不等值连接:连接条件不是等号

         示例:查询员工信息,要求显示:员工号,姓名,月薪,薪水的级别

     select * from emp;

    select * from salgrade;

    select e.empno,e.ename,e.sal,s.grade 

    from emp e,salgrade s where e.sal>=s.losal and e.sal<=s.hisal;--(具体问题,具体分析)注意大于等于下线,和小于上线

    select e.empno,e.ename,e.sal,s.grade 

    from emp e,salgrade s where e.sal between s.losal and s.hisal;--(between and包含两边边界值)

     5. 外连接

    select * from emp;

    select * from dept;

    select d.deptno,d.dname,count(e.empno)

    from dept d left join emp e on d.deptno=e.deptno

    group by d.deptno,d.dname;

    select d.deptno,d.dname,count(e.empno)

    from emp e left join dept d  on e.deptno=d.deptno

    group by d.deptno,d.dname;

     7. 自连接

    查询员工姓名和对应老板姓名

    select * from emp ;

    select e1.ename,e2.ename from emp e1,emp e2 where e1.mgr=e2.empno;--普通表连接自动顾略空值(14*14=196条记录)--如果一亿条数据表,则是平方关系

    select e1.ename,e2.ename from emp e1 left join emp e2 on e1.mgr=e2.empno;

    https://img1.sycdn.imooc.com//5cc5654400010f8705290311.jpg

     8. 层次查询(解决自连接问题)

    自连接存在的问题:不适合操作大表

    解决办法:层次查询(单表查询)

    原理:

    https://img1.sycdn.imooc.com//5cc567a500013acf01870325.jpg

    https://img1.sycdn.imooc.com//5cc567d30001c6a105130270.jpg

    条件:上层员工号是下层员工的老板号

              上一层的员工号=老板号

    select level,empno,ename,sal,mgr from emp 

    connect by prior empno=mgr

    start with empno =7893;

    select level,empno,ename,sal,mgr from emp

    connect by prior empno=mgr

    start with empno is null

    order by 1;(根节点)


    查看全部
    0 采集 收起 来源:[Oracle] 外连接

    2019-04-28

  • select d.deptno 部门号,d.dname部门名称,count(e.empno)人数

    from emp e,dept d  where e.deptno=d.deptno  group by d.deptno,d.dname;

    查看全部
    0 采集 收起 来源:[Oracle] 外连接

    2019-04-10

  • select e.empno,e.ename,e.sal,s.grade from emp e,salgrade s where e.sal between s.losal and s.hisal;

    查看全部

举报

0/150
提交
取消
课程须知
小伙伴们,学习本课程前需要掌握Oracle的语法基础,并且对Oracle的函数有所了解。如不了解这两部分内容,请移步《Oracle数据库开发必备利器之SQL基础》和《Oracle数据库开发利器之函数》两门教程。
老师告诉你能学到什么?
1、掌握分组查询 2、掌握多表查询 3、掌握子查询

微信扫码,参与3人拼团

意见反馈 帮助中心 APP下载
官方微信
友情提示:

您好,此课程属于迁移课程,您已购买该课程,无需重复购买,感谢您对慕课网的支持!