Oracle学习(三)

一.SQL99 中的内外连接
   1.1 sql99 中的内连接
   列出每个员工的 first_name  和对应的部门名
      select first_name,name
          from   s_emp  e, s_dept d
              where e.dept_id=d.id;
   from   a表  join  b表  on 连接条件; 
   from   a表 inner join  b表  on 连接条件;
    select first_name,name
          from   s_emp  e join s_dept d
              on e.dept_id=d.id; 
     select first_name,name
          from   s_emp  e inner join s_dept d
              on e.dept_id=d.id; 
  1.2 sql99 中的外连接
    a表  left  outer  join b 表 on 连接条件;
    a表  right  outer  join b 表 on 连接条件;
    a表  full  outer  join b 表 on 连接条件;
    
    /* (+) 字段对面的表的数据全部匹配出来 
       left outer join  就是左边的表发起
       连接,左边的表的数据全部匹配出来*/   
    增加一个新部门 
    insert  into  s_dept values(100,'test',NULL);
    commit; 
    列出所有的部门名 和 对应的地区名
    (+) 
       select  d.name,r.name    
           from  s_dept  d,s_region  r
               where d.region_id=r.id(+);
      left  outer  join 
       select  d.name,r.name    
           from  s_dept  d left outer 
               join s_region  r
               on d.region_id=r.id;   
      right  outer   join 
      select  d.name,r.name    
           from  s_region  r right outer join s_dept  d
               on d.region_id=r.id; 
      /* 使用左外连接 完成谁是普通员工?*/
      先使用 (+)   id  first_name 
         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;        
     全外连接的结果集 等于左外连接的结果集
     加上右外连接的结果集 然后减去重复的记录。
     oracle 如何实现全外连接?
     oracle不是通过两端都加(+) 
     是通过关键字 
     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;
     
     多表查询:
         内连接
             等值连接  
             非等值连接 
             自连接 
         外连接         
             等值连接  
             非等值连接 
             自连接 
  SQL99  内外连接
     内连接
     a表  join  b表  on  连接条件;
     a表  inner join  b表  on  连接条件;
     外连接
     a表 left outer join b 表 on 连接条件;
     a表 right outer join b 表 on 连接条件;
     a表 full outer join b 表 on 连接条件;
        union
        union  all
 二.组函数
    2.1 特点
    无论sql语句影响多少行 最终返回一个结果
    2.2 常见的组函数
    count    统计个数
    max      统计一组数据的最大值
    min      统计最小值
    sum      统计和
    avg      统计平均值
    2.3 举例
    统计  s_emp 表中的 员工人数 工资的
    最大值  工资的最小值
    select  count(id),max(salary),
        min(salary)  from s_emp; 
    2.4 统计s_emp 中的工资的和  和 
       工资的平均值。
    select  sum(salary),avg(salary)
        from s_emp;   
    select  sum(distinct salary),
        avg(distinct salary)
        from s_emp;      
    2.5 测试组函数对NULL值的处理方式
    统计s_emp提成的个数  提成的平均值
    忽略
    select  count(commission_pct),
        avg(commission_pct) from  s_emp; 
       
 三.分组
    3.1  按照一定的标准 把数据分成若干组。
    3.2  where 条件 group  by  分组标准.
    3.3  按照部门编号分组 统计每个部门的人数
     select  dept_id,count(id)
         from  s_emp 
             where  1=1
                 group by   dept_id;
    3.4   按照部门编号分组 统计每个部门的
      平均工资。
     select  dept_id,avg(salary)
         from  s_emp 
             where  1=1
                 group by   dept_id;
     按照部门编号分组 统计每个部门的
      平均工资。列出平均工资大于1400的部门
      和 平均工资。 
     select  dept_id,avg(salary)
         from  s_emp 
             where  1=1 
                 group by   dept_id;    
    3.5 如何对组数据进行过滤 
       需要使用 having  数据过滤条件 
     select  dept_id,avg(salary)
         from  s_emp 
             where  1=1 
                 group by   dept_id
                     having avg(salary)>1400;
    3.6 按照部门号分组  统计每个部门的人数
      显示人数大于2的部门编号 和 人数。
     select  dept_id,count(id) ec
         from  s_emp  
             group  by  dept_id
                 having  count(id)>2
                     order by ec;  
     from  
         where 
             group by 
                 having 
                     select   
                         order by 
   3.7  列出每个部门的平均工资  
       要求显示平均工资大于1400的部门
       编号和 平均工资。还要求显示部门名。
       s_emp   s_dept
   select dept_id,avg(salary),d.name    
       from  s_emp e,s_dept d
           where  e.dept_id=d.id 
               group by  dept_id,d.name
                   having avg(salary)>1400;
       
   select dept_id,avg(salary),max(d.name)    
       from  s_emp e,s_dept d
           where  e.dept_id=d.id 
               group by  dept_id
                   having avg(salary)>1400;    
   结论:在分组语句中  select 后的字段 要么
   是分组标准要么是经过合适的组函数处理过的。    
                             
四.子查询
   4.1 概念
   把一条sql 的执行结果  另一条sql的操作基础。
   4.2 子查询出现的位置
   where 
   having 
   from
   4.3  where 之后
   /* 查询所有的领导编号 */
   select  distinct  manager_id from s_emp;
   /* 如果一个员工的编号 出现在领导编号中
   则这个员工是领导*/
   in 等于其中的任何一个
   select  id,first_name  from s_emp
       where id  in (select  distinct 
        manager_id from s_emp);
   /* 查询所有的非领导 列出 id ,first_name*/
   not in 不等于其中任何一个数据
   id  not in (1,2,3,NULL);
   select  id,first_name  from s_emp
       where id not in (select  distinct 
        manager_id from s_emp);
   
   select  id,first_name  from s_emp
       where id not in (select  distinct 
        manager_id from s_emp where
        manager_id is not null);
          
   4.4  子查询出现在having 后 
   按照部门号分组,列出每个部门的平均工资
   要求显示平均工资大于42部门的平均工资
   的部门,显示部门号 和平均工资.
   select  dept_id ,avg(salary)
       from  s_emp   
           group by  dept_id
               having  avg(salary)>(
               select  avg(salary) from 
               s_emp where dept_id=42);
   4.5  子查询出现在from之后
   任何的查询语句 可以看成一张内存表
   select id,first_name name ,salary
       from s_emp; 
   select * from  ( select id,first_name 
   name ,salary from s_emp )  
   where salary>1000; 
   
   
   select*from(select  dept_id ,avg(salary) 
       asal from  s_emp   
       group by  dept_id) where asal>(
        select  avg(salary) from 
        s_emp where dept_id=42);
五.建表 和 删表
   5.1 建立表
   create  table  表名(
       字段名    类型,
       字段名    类型,
       字段名    类型 
   );
   类型:
   number
   name   char(20)    定长字符串  
   name   varchar2(20) 变长字符串
   date   日期类型
   5.2 建立一张员工表
   create  table  myemp9528( 
   id     number,
   fname  char(10),
   sname  varchar2(10),
   salary number
   );
   5.3 删除表
   drop   table   myemp9528;   
   create  table  myemp9528( 
   id     number,
   fname  char(10),
   sname  varchar2(10),
   salary number
   );
   
六.DML (数据操作语句)
   6.1  insert  增加数据
   insert   into  表名  values(字段1值,
   字段2值,字段3值);   
   insert   into  myemp9528 values(
   9527,'xsy','xsy',123456);
   commit;
    
   select  length(fname),length(sname)
       from myemp9528 where id=9527;
   select * from myemp9528 
       where fname='xsy ';
   select * from myemp9528 
       where sname='xsy';    
   
   可以选择部分字段 插入值 
   没有选择的字段 以NULL值插入
   必须包含所有的非空字段
   insert  into 表名(字段名1,字段名3)
   values(字段1值,字段3值);
   
   insert  into myemp9528(id,sname)
   values(2008,'bjtest');
   commit;
   select  * from myemp9528;
   
   insert   into s_dept values(100,
   'test',NULL);
   
   insert  into myemp9528(id,sname)
   values(1,'bdl');
   commit;
  
  6.2 删除数据
  delete  from  表名  where  条件;
  commit;
  
  delete  from  myemp9528 where id=1;
  commit; 
    
  6.3 更新数据
  update   表名    set 字段1名=值
      where 条件;
  update   表名    set 字段1名=值1,
      字段2名=值2 
          where 条件;    
  commit; |  rollback; 
  update   myemp9528  set salary=8888
      where sname='bdl'; 
  update   s_emp   set salary=12500
      ,first_name='bdl' where id=12;    
  commit;
   
 七.事务 (交易) 
  commit;  提交
  rollback; 回滚
  savepoint  保存点名;
  
  原子性:
      事务中的操作 是一个不可分割的整体。
      转账
      update  account 
      set salary=salary-20000 where ano='1';
      a 
      update  account 
      set salary=salary+20000 where ano='2';
      b
      if(a&&b){
          commit;
      }else{
          rollback;
      }
      事务中的操作 要么一起成功 要么一起失败
  隔离性:
      一个事务中的操作 在没有提交以前 对
      另一个事务而言 数据的变化是不可见的。
      drop     table  testtcl;
      create   table  testtcl(
          id   number primary key,
          salary  number
      );
      insert  into  testtcl values(1,2000);
      insert  into  testtcl values(2,4000);
  一致性:
      -20000;
      +20000
      -50
      
  持久性:
       
   
  保存点:
      让事务做到 部分成功 部分失败。
      insert 
      savepoint  a;
      update
      savepoint  b;
      insert 
      savepoint  c;
      
      if(c){
          rollback to b;
          commit;
      }
      
      drop     table  testtcl2;
      create   table  testtcl2(
          id   number primary key,
          salary  number
      );  
     insert  into  testtcl2 values(2,2000);
     savepoint  a;
     insert  into  testtcl2 values(3,3000); 
     savepoint  b;
     insert  into  testtcl2 values(4,4000);
     savepoint  c;
     insert  into  testtcl2 values(5,5000); 
     savepoint  d;
     rollback to b; 
     commit; 
     
八.日期类型 
   date
   8.1 日期类型的表达
   'dd-MON-yy'
   select  start_date from s_emp; 
   8.2 把s_emp 表中 id  first_name start_date
   要求按照start_date排序
   select  id,first_name,start_date
       from  s_emp  order by start_date;
   8.3 日期格式显示
   to_char(日期数据,'日期格式')
   yyyy   四位年
   mm     2位月
   dd     两位天
   
   hh     12小时制
   hh24   
   mi     分钟
   ss     秒
   
   day    星期几
   month  月的全写
   mon    月的缩写
   pm     上午am  下午pm  
   
   select  id,first_name,
     to_char(start_date,
     'yyyy-mm-dd hh24:mi:ss')
     from  s_emp  order by start_date; 
     
   select  id,first_name,
     to_char(start_date,
     'yyyy-mm-dd hh24:mi:ss day  pm')
     from  s_emp  order by start_date;  
   8.4 如何插入日期
   建立一张订单表
   drop    table  myorder9527;
   create  table  myorder9527(
   ono     varchar2(50) primary key,
   oname   varchar2(30),
   omoney  number,
   odate   date
   );
   insert  into myorder9527 values(
   'bj002','test002',168.75,'18-AUG-14');
   commit;
   
   select  ono,to_char(odate,
      'yyyy-mm-dd hh24:mi:ss')  
      from myorder9527;
   8.5 直接插入当前系统时间
   insert  into myorder9527 values(
   'bj003','test003',168.75,sysdate);
   commit;  
   
   to_date('日期字符串','日期格式')
   根据日期格式 把日期字符串 转换成日期
   2008-08-08  20:08:08 
   2012-12-21  23:59:59
   2020-01-01  00:48:15 
   
        
                                                                                                                        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值