Oracle 笔记02

显示first_name 的后三个字符
hello
12345
54321
select first_name,substr(first_name,-3,3) 
from s_emp;


函数嵌套:
确定一个字符串的倒数第三个字符
select first_name,
substr(first_name,length(first_name)-2,3) 
from s_emp;


数字的单行函数:
round    ------四舍五入
select round(49.9)  from dual;//50
select round(49.9,0)  from dual;//50
select round(49.77,1)  from dual;//49.8
select round(49.774,2)  from dual;//49.77
select round(49.77,-1)  from dual;//50
select round(49.774,-2)  from dual;//0
select round(59.774,-2)  from dual;//100
trunc    ------截取
select trunc(49.9)  from dual;//49
select trunc(49.9,0)  from dual;//49
select trunc(49.77,1)  from dual;//49.7


格式显示函数
to_char(参数1,参数2) 
参数1 要处理的数据
参数2 格式字符串(不是必须的)
如果没有参数2 则把任何类型转成字符串
有参数2
fm   格式说明符 这个不是必须的
9    代表任意数字
0    强制显示前导零 9   009
L    本地货币符号   ¥   RMB
$    美元符号
.    小数点
,   国际货币分隔符号 10000  10,000 


select salary,to_char(salary,'fmL099,999.00')
from s_emp;


select to_char(2500.88,'L099,999.99')  from dual;
select to_char(2500.88,'L099,999.00')  from dual;


验证你的语言环境
select userenv('lang')  from dual;


1.退出sqlplus
2.如果系统的shell不是bash  则切换shell  
   bash
3.回到主目录  
   cd
4.编辑配置文件  
  vi  .bash_profile
  NLS_LANG='SIMPLIFIED CHINESE_CHINA.ZHS16GBK'
  export NLS_LANG
5.保存退出
6.source  .bash_profile
7.重新进入sqlplus 
8.验证语言环境 
  SQL>select userenv('lang')  from dual;
  SQL>ZHS 


如果想切换成英文
  NLS_LANG='AMERICAN_AMERICA.ZHS16GBK'
  export NLS_LANG


-----------------------------------------
函数嵌套
列出first_name ,manager_id   
如果manager_id 是NULL 则显示成'BOSS'
select  first_name,
nvl(to_char(manager_id),'''BOSS''')
from s_emp;


--------------------------------------------
F.多表查询(最重要的内容)
列出first_name,dept_id 
select first_name,dept_id  from s_emp;


s_emp   ,s_dept
 Name
 --------------
 ID          部门编号
 NAME        部门名称
 REGION_ID   地区编号 
列出first_name,dept_id ,部门名称


s_emp  25
s_dept 12
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=s_dept.id;


select first_name,dept_id,s_dept.id,name  
from s_emp,s_dept
where dept_id=s_dept.id;


表连接的种类:
等值连接:用等号做为连接符号
介绍另一张表  s_region(地区表)
 s_dept   部门表
 Name
 --------------
 ID          部门编号
 NAME        部门名称
 REGION_ID   地区编号 


 s_region  地区表
 Name
 -------------
 ID      地区编号
 NAME    地区名称
 列出部门名称   和每个部门属于的地区名称
  select s_dept.name,s_region.name
     from  s_dept,s_region
         where  region_id=s_region.id;


select s_dept.name,region_id,s_region.id,
s_region.name
     from  s_dept,s_region
         where  region_id=s_region.id;


col name for  a15
设置某一列的宽度(查询语句之前使用)


非等值连接:不用等号做连接符号
SQL> select * from salgrade;


     GRADE      LOSAL      HISAL
---------- ---------- ----------
         1        700       1200
         2       1201       1400
         3       1401       2000
         4       2001       3000
         5       3001       9999
列出s_emp表中每个人 first_name的工资级别
select first_name,salary,grade
    from  s_emp,salgrade
    where salary  between losal and hisal; 


等值连接和非等值连接 都是内连接
内连接:符合连接连接条件就被选中 不符合
连接条件就被过滤掉
内连接中的有种特殊的连接------自连接
s_emp 
id   first_name   manager_id        
 1    Carmen      
 2    test        1
 3    hello       1
 4    world       2
 
 3号和4号不是别人的manager_id
 领导----这个员工id是别人的manager_id 
 物理上只有一张表  
  
 列出所有领导的first_name (8个)
 select distinct manager_id from s_emp 
     order by manager_id;
补充:排序中把NULL值做为最大值处理
 select first_name,manager_id from s_emp
     where  id=manager_id;
     //上面的是找自己管自己的员工
 逻辑上考虑成两张表  解决树状关系   
   select distinct m.first_name,m.id
        from   s_emp m,s_emp e 
   where  m.id=e.manager_id
   order by m.id;
  
内连接:等值 
        非等值
自连接 


一共有25个员工  找出了8个领导  
写一条sql把17个普通员工列出来 
列出first_name  id  manager_id


select distinct m.first_name,m.id
        from   s_emp m,s_emp e 
   where  m.id!=e.manager_id;
查出了8个领导  -----内连接
 select distinct m.first_name,m.id
        from   s_emp m,s_emp e 
   where  m.id=e.manager_id;


外连接的结果集=内连接的结果集+过滤掉的数据
select distinct m.first_name,m.id
        from   s_emp m,s_emp e 
   where  m.id=e.manager_id(+);
需要领导表中所有的数据
(+)对面的表的数据全部匹配出来
要普通员工
select distinct m.first_name,m.id
        from   s_emp m,s_emp e 
   where  m.id=e.manager_id(+)
   and  e.manager_id is null;
要领导
select distinct m.first_name,m.id
        from   s_emp m,s_emp e 
   where  m.id=e.manager_id(+)
   and  e.manager_id is not null;


列出s_emp表中每个人 first_name的工资级别
s_emp   salgrade
 select first_name,salary,grade
    from  s_emp,salgrade
        where salary between  losal and hisal;
update  s_emp  set salary=12500 where id=1;
commit;
你要所有员工  还是所有的工资级别?
 select first_name,salary,grade
    from  s_emp,salgrade
        where salary between  losal(+) and hisal(+);
 要那些没有工资级别的人
 select first_name,salary,grade
    from  s_emp,salgrade
        where salary between  losal(+) and hisal(+)
and  losal is null and  hisal is null;


列出所有的部门名称 对应的地区名称
s_dept     s_region
关系
region_id=s_region.id
select s_dept.name,s_region.name   
   from  s_dept,s_region
       where region_id=s_region.id;
//12 row被选中  
公司成立了新的部门  编号100
insert into s_dept values(100,'test',NULL);
commit;
列出所有的部门名称 对应的地区名称
我们需要部门表中所有的数据  你要把(+)加在那
一端?
select s_dept.name,s_region.name   
   from  s_dept,s_region
       where region_id=s_region.id(+);
select s_dept.name,s_region.name   
   from  s_dept,s_region
       where s_region.id(+)=region_id;
SQL99标准
左外连接  ----left  outer join  
右外连接  ----right outer join
全外连接  ----full  outer join




inner  join      简写为  join
查询部门名称和它对应的地区名称
select s_dept.name,s_region.name   
    from  s_dept,s_region
        where region_id=s_region.id;
了解下面的写法:
select s_dept.name,s_region.name   
    from  s_dept join s_region
        on region_id=s_region.id;
select s_dept.name,s_region.name   
    from  s_dept inner join s_region
        on region_id=s_region.id;
列出所有的部门名称 和对应的地区名称
我们需要部门表中所有的数据  
要考虑让那张表
发起连接  如果那张表发起外连接则那张表的数据
全部被显示出来  
select s_dept.name,s_region.name   
    from  s_dept left outer join s_region
        on region_id=s_region.id;
select s_dept.name,s_region.name   
    from  s_region right outer join s_dept
        on region_id=s_region.id;
如果要过滤数据 需要使用where条件
select s_dept.name,s_region.name   
    from  s_region right outer join s_dept
        on region_id=s_region.id
where  s_region.id is null;


全外连接=左外连接+右外连接 去掉重复的数据


oracle如何实现全外连接:
不是两端都加(+)  而是使用uinon  和 union all
实现


uinon      合并两个结果集然后排重
select  id  from s_emp   union
select  id  from s_emp;//25
union all  合并两个结果集不排重
select  id  from s_emp   union all
select  id  from s_emp;//50


连接-----内连接----等值 非等值  自连接
    -----外连接----等值 非等值  自连接
           
-----------------------------------------
G 组函数和分组
  常见的组函数
  count()  ------统计个数
  max()    ------求最大值
  min()    ------求最小值      
  avg()    ------求平均值
  sum()    ------求和


对一组数据处理之后 得到一个结果
select   max(salary)  from s_emp;


统计s_emp表中提成的平均值?
select avg(commission_pct)  from s_emp;
组函数对NULL  忽略


select avg(distinct commission_pct)  from s_emp;


按照部门号  分组  统计每个组的员工数
group by  分组标准
select   dept_id,count(id)  
    from s_emp  
        group by  dept_id;


按照部门号  分组  统计每个组的平均工资
把部门名称显示出来
select   dept_id,avg(salary),name  
    from s_emp,s_dept
        where dept_id=s_dept.id
        group by  dept_id,name;
同一个部门id 肯定对应同一个部门名称
select   dept_id,avg(salary),name  
    from s_emp,s_dept
        where dept_id=s_dept.id
        group by  dept_id;
在分组的语句中  出现在select后的字段
要么是分组标准  要么要经过组函数处理 
select   dept_id,avg(salary),min(name)  
    from s_emp,s_dept
        where dept_id=s_dept.id
        group by  dept_id;
思考:如何只显示平均工资大于1500的
对分组后的数据进行过滤 要采用having
having 出现group by 之后
select   dept_id,avg(salary),min(name)  
    from s_emp,s_dept
        where dept_id=s_dept.id 
        group by  dept_id
having  avg(salary)>1500;


select   dept_id,avg(salary) asal,min(name)  
    from s_emp,s_dept
        where dept_id=s_dept.id 
        group by  dept_id
having  avg(salary)>1500
order by  asal;


执行顺序:
    from
    where 
    group by 
    having 
    select
    order by


group  by  分组标准
对组数据过滤  使用having
select 后的字段 要么是分组标准
要么使用组函数进行处理
sql的执行顺序是什么
---------------------------------------
G.子查询
  把一个sql的查询结果 
  作为另一个sql的查询基础


  可以使用子查询的位置
  where后
  谁是领导?8
  //得到所有领导的id  和NULL
  select distinct manager_id from s_emp;


  select first_name,id from s_emp  
  where id in (select distinct 
  manager_id from s_emp);
    select first_name,id from s_emp  
  where id in (1,2,3,6,7,8,9,10,NULL);
  使用子查询查出所有的普通员工?
  
  如果子查询返回多个结果 则不能使用等号
  找出和id是1的 职位相同的员工?




  from 后
  from (子查询)
  这时的子查询实际上是一张内存表
  任何sql语句都是一张内存表
  select  dept_id,max(salary) sal from s_emp 
  group by  dept_id;
  select  * from (select  dept_id,max(salary) sal from s_emp 
  group by  dept_id) where sal>1500;
  having 后
  查询50部门的平均工资


  求平均工资大于50部门平均工资的部门名称
  select  avg(salary) from s_emp 
  where dept_id=50;


  select dept_id ,avg(salary)  from s_emp 
      group by dept_id
      having avg(salary)>(select  avg(salary) from s_emp 
  where dept_id=50);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值