Oracle03

1.按照salary排序 显示s_emp 表中的 id first_name salary 如果工资相同

  则使用 first_name 降序排列 

2.写出处理字符串的 函数有哪些  写 5 个

3.分别写出 round(12.88)  trunc(12.88)  round(12.88,1)  trunc(12.88,1)

  round(3.33)  trunc(3.33)  的值

4.显示 s_emp 表中first_name 的前三个字符  和 后三个字符  并把这些数据 变大写

5.显示s_emp 表中第三个字符是a的 first_name 

6.显示 s_emp 表中 manager_id 是NULL的员工 显示 id first_name  salary

7.显示 s_emp 表中  first_name 叫 Carmen  并且  salary 等于 2500 的员工

显示  id  first_name  salary

  select  id,first_name,salary from  s_emp

      where  first_name='Carmen' and  salary=2500; 

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

1.多表查询  10*10*10

  1.1 为什么要有多表查询

    需要的数据 已经被分散多张表中了。

  1.2 如何实现?

    查询 每个员工的  first_name  和 对应的部门编号

  select  first_name,dept_id from  s_emp;   

    在上面查询的基础上 显示部门名

  select  first_name,dept_id,name

        from  s_emp,s_dept;

    上面的查询 产生了一个超大集合 叫 笛卡尔积     

    select  first_name,dept_id,name

        from  s_emp,s_dept where  dept_id=id;

  上面的语句出错 需要使用规则:多张表中有同名的字段  使用 表名 点 区分

    select  first_name,dept_id,name

        from  s_emp,s_dept

            where  dept_id=s_dept.id;

  1.3 语法

select 需要的字段

    from  表1,表2  where  表的连接条件;

  1.4 练习

  s_dept  部门表                                  s_region  地区表

  id    number  部门编号                  id        number  地区编号 

  name  varchar2(25) 部门名            name      varchar2(25) 地区名

  region_id  number  地区编号

  显示 每个部门的名字  和 对应的地区的名字 

  select  s_dept.name,s_region.name

    from  s_dept,s_region

        where  region_id=s_region.id;

  1.5 使用表的别名 简化查询

  select  d.name,r.name

      from  s_dept d,s_region  r

        where  region_id=r.id;


  1.6 等值连接 和 非等值连接

    员工  和  部门    dept_id = s_dept.id 

    部门  和  地区    region_id = s_region.id

    表达两张表的关系 使用等号  则称之为 等值连接。 

    如果连接两张表的关系 不使用等号 则称之为非等值连接

  salgrade  工资级别表

  SQL> desc salgrade;

Name

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

GRADE    级别

LOSAL    级别对应的低工资

HISAL    级别对应的高工资

  显示 s_emp 表中 每个人的id , salary  和 salary 对应的工资级别 

  select  id,salary,grade   

      from  s_emp,salgrade

          where  salary  between  losal  and  hisal;

  1.7 自连接

    一张物理表中  存储了两层业务含义的数据  要把其中的一层业务含义的数据查询出来 就需要

    使用到自连接的语法。

  s_emp 

    领导

    普通员工 

    把所有的领导查询出来?

  id      manager_id

  80      60

  100      100

  101      100

  102      100

  110      100

  select  id,first_name from  s_emp where  id=manager_id; 

      当有人的manager_id  是你的id 时  则 你就是领导


  select distinct m.id,m.first_name

        from  s_emp  e,s_emp m  where e.manager_id = m.id;

  8 个领导


  25-8=17个普通员工    下面的写法错误 

  select distinct m.id,m.first_name

        from  s_emp  e,s_emp m  where e.manager_id != m.id;


2.内连接

      内连接的特点就是 符合连接条件的数据 被选中  不符合连接条件的数据被过滤掉。

      上面的  等值连接    非等值连接  自连接 都是内连接。

3.外连接

3.1 概念和实现

  外连接的结果集 等于 内连接的结果集  加上 匹配不上的记录

(一个也不能少) 

  如何实现?

  (+)  (+) 所在的表的字段 对面的表的数据全部被匹配出来

              底层通过 NULL 记录匹配出来的 

  select distinct m.id,m.first_name

        from  s_emp  e,s_emp m  where e.manager_id(+) = m.id

        and  e.manager_id is null;

3.2 练习  s_emp  s_dept

      显示每个员工的id, first_name  和 对应的 部门名(name)

    select  e.id,first_name,name

        from  s_emp e,s_dept d

            where  e.dept_id=d.id;

      公司为了业务发展 需要抽调一部分人出来  这些人将离开原来的部门

  update  s_emp  set dept_id = null where id < 3;

  commit;

      显示每个员工的id, first_name  和 对应的 部门名(name)  没有部门编号的员工也要显示

  select  e.id,first_name,name

        from  s_emp e,s_dept d

            where  e.dept_id=d.id(+); 

3.3 练习  s_dept    s_region

    显示每个部门的名字  和 对应的地区的名字

  select d.id, d.name,r.name

      from  s_dept  d,s_region r

          where  d.region_id = r.id; 

  公司业务扩大了  增加了一些新的部门

  insert  into  s_dept  values(100,'test100',NULL);

  insert  into  s_dept  values(101,'test101',NULL);

  commit;                     

  显示每个部门的名字  和 对应的地区的名字  没有地区编号的部门也要显示 

  select d.id, d.name,r.name

      from  s_dept  d,s_region r

          where  d.region_id = r.id(+);         

  3.4 非等值连接的外连接    salgrade  s_emp

    列出每个员工的 id  salary  和  salary 对应的工资级别

  select id,salary,grade

      from  s_emp,salgrade

          where salary  between  losal and hisal;

  把 id = 25  和 id=24 的这两个人的工资 改成 12345

  update  s_emp  set  salary=12345 where id >= 24;

  commit;

  列出每个员工的 id  salary  和  salary 对应的工资级别  超出统计范围的员工也要显示

  select id,salary,grade

      from  s_emp,salgrade

          where salary  between  losal(+) and hisal(+);

  4.表连接

    内连接

            等值连接    员工和部门      部门和地区       

            非等值连接  员工的工资 和 对应的工资级别

            自连接          谁是领导?

    外连接

            等值连接    员工和部门 (找出没有部门的员工)      部门和地区 (没有地区编号的部门)       

            非等值连接  员工的工资 和 对应的工资级别  (超出统计范围的工资)

            自连接          谁是普通员工?


      外连接的结果集 等于 内连接的结果集  加上匹配不上的记录

            如何实现的?

      (+)  (+)的意思所在字段的对面的表的数据全部被匹配出来

            本质上 底层是通过 NULL 记录进行的匹配

  5.SQL99 内外连接

    5.1 内连接标准

    from  a表  join b表  on 连接条件  where 过滤条件;

    from  a表  inner join b表  on 连接条件  where 过滤条件;

          显示 每个部门的名字 和 对应的地区的名字

      select  d.name,r.name

          from  s_dept d,s_region r

              where  d.region_id = r.id;

    select  d.name,r.name

          from  s_dept d  join s_region r

              on  d.region_id = r.id;

    select  d.name,r.name

          from  s_dept d  inner  join s_region r

              on  d.region_id = r.id;

    5.2 外连接的标准

    a表  left outer  join  b 表  on 表的连接条件  where  过滤条件;

    a表  right outer  join  b 表  on 表的连接条件  where  过滤条件;

    a表  full  outer  join  b 表  on 表的连接条件  where  过滤条件;


    a表  left outer  join  b 表  就是a表发起连接  意思就是a表的数据全部被匹配出来。

    a表  right outer  join b 表  就是b表发起连接  意思就是 b表的数据全部被匹配出来。

          本质上也通过 NULL 记录进行的匹配

          显示每个部门的名字  和 对应的地区的名字  没有地区编号的部门也要显示 

      select d.id, d.name,r.name

          from  s_dept  d,s_region r

              where  d.region_id = r.id(+); 


      select d.id, d.name,r.name

          from  s_dept  d left outer  join s_region r

              on  d.region_id = r.id;


      select d.id, d.name,r.name

          from  s_region r  right outer  join  s_dept  d

              on  d.region_id = r.id;     

              使用左外连接  实现 s_emp 谁是普通员工的问题 显示  id  first_name

              谁是领导?40  谁是普通员工 40  改成 left outer  join  20

        select distinct m.id,m.first_name

            from  s_emp  e,s_emp m

                where  e.manager_id(+) = m.id and e.manager_id is null;       

      select distinct m.id,m.first_name

            from  s_emp  m  left outer join s_emp e

                on  e.manager_id = m.id where e.manager_id is null;


      select distinct m.id,m.first_name

            from  s_emp  m  left  join s_emp e

                on  e.manager_id = m.id where e.manager_id is null;


      5.3  full outer join 

            全外连接 只是一个逻辑概念,代表左外连接的结果集 加上 右外连接的结果集 然后

                  排除重复的记录。

      Oracle 中如何实现全外连接呢? 不是通过两端都加(+) 实现的。

            而是通过  union    来实现的 , union 的意思是 合并两个结果集  然后排重。

      union  all  合并两个结果集  不排重。

      select  id from  s_emp  union  select id from s_emp;

      select  id from  s_emp  union  all select id from s_emp;             

  6.组函数

    6.1 特点

        对一组数据处理 最终返回一个结果  无论sql语句影响多少行 最终只有一个结果。

    6.2 常见的组函数

    max(par1)  统计最大值

    min(par1)  统计最小值

    avg(par1)  统计平均值

    sum(par1)  统计和

    count(par1)  统计个数

    6.3 练习

        统计s_emp 表中的最高工资  最低工资  员工的个数

    select  max(salary),min(salary),count(id)  from  s_emp;

        统计s_emp 表中的工资的和  以及 工资的平均值

    select  sum(salary),avg(salary)  from  s_emp;

    6.4 特殊用法

        在count 中可以使用  *

    select  count(*) from  s_emp;

        组函数中可以使用  distinct

    select  sum(distinct salary),avg(salary)  from  s_emp;   

    6.5 组函数 对NULL 值如何处理?  忽略

    select max(manager_id) from s_emp;

    select avg(manager_id) from s_emp;


    7.分组

    7.1 概念

        按照一定的标准  把数据分割成若干部分

    7.2 提出问题

        按照部门编号分组 统计每个部门的人数

    dept_id    count

    41          3

    42          4

    50          2

    7.3 sql 中如何完成

    select  字段名,统计的数据  from  表名    where 条件

        group by 分组标准  having  组数据过滤条件 

            order by 排序标准;

按照部门编号分组  统计 每个部门的人数    显示 部门编号 和 平均工资           

select dept_id,count(id) 

    from  s_emp 

        group  by  dept_id;


    按照部门编号 分组  统计 每个部门的平均工资  显示 部门编号 和 平均工资

  select dept_id,avg(salary) 

      from  s_emp 

        group  by  dept_id;   

  7.4 练习  s_dept

      按照地区编号 分组  统计每个地区中的部门个数  显示地区编号 和 部门个数

select region_id,count(id)

  from  s_dept

      group by region_id;

  要求地区中部门个数大于2 的显示 

select region_id,count(id)

    from  s_dept

        group by region_id  having count(id) > 2; 

  7.5 按照部门编号分组  统计每个部门的平均工资  要求平均工资大于1400 的 显示

  select  dept_id,avg(salary)     

      from  s_emp 

          group by  dept_id  having  avg(salary) > 1400;


  having 执行早  还是  select 执行早?

你可能感兴趣的:(Oracle03)