Oracle day03 火推

 Oracle 03



函数

Oracle在编写时 内置了一些函数
单行函数

返回的结果. 针对每一行数据, 都会计算出一个结果

单行函数的案例: 
    查询员工的last_name , 并将last_name转换为全大写字母 !

    select upper(last_name) from s_emp;
    select last_name from s_emp;
组函数

返回的结果, 无论存在多少行数据, 都只返回一个结果

计算s_emp表格存在多少行数据 !


组函数存在一些使用上的限制 , 要求返回的结果要一一对应!

select count(id),last_name from s_emp;(错误案例)
select count(id) from s_emp;
常用单行函数

dual 系统提供用来测试学习单行函数的!
字符串的单行函数

1.  字符串变大写
    upper(文本/字段)
    案例: select upper('zhiqiang') from dual;

2.  字符串变小写
    lower(文本/字段)
    案例: select lower('ZHIQIANG') from dual;

3.  单词首字母大写
    initcap(文本/字段)
    案例: select initcap('zhi qiang') from dual;

4.  获取字符串的长度 *
    length(文本/字段)
    案例: select length('zhi qiang') from dual;
5.  截取字符串   *
    substr(参数1,参数2,参数3)

    参数1.    要被截取的原字符串/字段
    参数2.    截取开始的下标,从1开始,可以输入负数
    参数3.    截取的长度


    案例: 

        select substr('123456789',1,5) from dual;   \
                                                        结果完全一致
        select substr('123456789',0,5) from dual;   /


    开始截取的下标 ,输入负数

        select substr('123456789',-3,3) from dual;

6.  拼接字符串

    concat(参数1,参数2)

    参数1. 拼接字符串元素1
    参数2. 拼接字符串元素2

    select concat('zhiqiang','shuaibi') haha from dual;

7.  替换字符串中的指定内容 *

    replace(参数1,参数2,参数3)

    参数1.    要被替换内容的原字符串
    参数2.    在参数1中存在的, 要被替换的字符串片段
    参数3.    替换的新的字符串片段

    select replace('123456789','123','abc') from dual;


8.  判断字符串是否为空 *
    nvl(参数1,参数2)

    参数1如果为空则返回参数2,  不为空则返回参数1

    参数1. 被判断是否为空的参数
    参数2. 如果参数1为空, 则返回此替代参数  
number类型的操作

1.  round(参数1,参数2)  四舍五入 *
    参数1.    要四舍五入的数字
    参数2.    保留的小数点后的位数 ,可以省略 默认为0

    案例: 
        select round(15.5555) from dual;
        select round(15.5555,3) from dual;

2.  trunc(参数1,参数2) 截取数字 *

    参数1.    要截取的数字
    参数2.    保留的小数点后的位数 ,可以省略 默认为0

    案例: 
        select trunc(15.5555) from dual;
        select trunc(15.5555,3) from dual;


3.  格式化显示数字

    ¥020,000.00
    to_char(参数1,参数2)

    参数1. 格式化的数字/列名
    参数2. 格式化模版 , 是一个字符串类型的参数, 需要添加单引号

        FM  :   格式的开头 ,可以忽略

        L   :   本地货币单位, Oracle的语言环境

        $   :   美元符号

        9   :   两种情况:
                    1.  数字9出现在小数点后面:表示1-9的任意数字
                    2.  数字9出现在小数点前面:表示0-9的任意数字

        0   :   两种情况:
                    1.  数字0出现在小数点后面:表示0-9的任意数字
                    2.  数字0出现在小数点前面,且在数字最前面:表示强制显示前导零
        .   :   小数点

        ,   :   分隔符


    案例: 查询s_emp表格中的所有员工的月薪(salary), 并将其格式化 , 
    格式:FM$099,999.00   |  FM$099,999.99
    //建议在小数点后面描述数字时, 使用0

    select to_char(salary,'FM$099,999.00'),id from s_emp;
函数的嵌套

    把一个函数返回的结果, 当作另一个函数所需要的参数 !

    需求: 查询s_emp表格中的last_name , 并且将其最后三位字母以大写方式显示出来 !

    select upper(substr(last_name,-3,3)) from s_emp;

    select upper(substr(last_name,length(last_name)-3,3)) from s_emp;
多表查询
当我们要查询的数据 存在多个表格中时, 需要用到多表查询技术
内连接

s_emp 员工表

s_dept 部门表

    -   id      部门编号
    -   name    部门名称
    -   region_id   部门所在地区编号

s_region 地区表
    -   id      地区编号
    -   name    地区名称

查询部门表格: 

    select id from s_dept;


多表查询基本语法: 

    select 字段 from 表名1,表名2...表名n;

查询部门表和员工表
    select name,last_name from s_emp,s_dept;
笛卡尔积

笛卡尔积是同一种关系代数概念(X*Y)

在SQL中的实现方式时交叉连接, 表示两个表中的每一行数据任意组合, 自然匹配 !
如何解决笛卡尔积

    在实际的SQL的应用中, 笛卡尔积本身没有实际用处.

    我们可以手动指定多张表格之间的关联关系, 来进行限制迪卡尔积的产生 !

    例如: 查询员工表格与部门表格,通过s_emp表格中的dept_id与s_dept表格中的id 关联 ,进行查询

    select last_name,name from s_emp,s_dept where dept_id=s_dept.id;
如何解决错误(未明确定义列)

一般是我们在进行多表查询时, 字段在多表中有重复, oracle无法区分字段所属的表格 .

可以将字段修改为:   表格名.字段 , 来明确字段所属的表格
等值连接

使用等号进行连接多表查询的条件, 就是等值连接
给表格起别名, 简化sql语句, 提高sql语句的可阅读性

查询员工表格与部门表格,通过s_emp表格中的dept_id与s_dept表格中的id 关联 ,进行查询

格式: from 表名1 别名1,表名2 别名2;
select e.id,d.id,e.last_name,d.name from s_emp e,s_dept d where e.dept_id=d.id;
练习

查询如下两张表, 要求消除笛卡尔积

格式: select 字段 from 表名1,表名2...表名n where 多表关联条件;

s_dept 部门表

    -   id      部门编号
    -   name    部门名称
    -   region_id   部门所在地区编号

s_region 地区表
    -   id      地区编号
    -   name    地区名称

    select d.name,r.name from s_dept d,s_region r where d.region_id=r.id;
非等值连接

引入脚本: demobld.sql

不使用等号进行连接多表查询的条件, 就是非等值连接

salgrade    :   工资级别表格

    -   grade工资级别 1-5
    -   losal这个级别最低工资
    -   hisal这个级别最高工资

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

查询每个员工的salary和对应的工资级别

1.  between

    select salary,last_name,grade from s_emp,salgrade where salary between losal and hisal;

2.  and

    select salary,last_name,grade from s_emp,salgrade where salary>=losal and salary<=hisal;
自连接

一张表中, 有多层的业务含义的数据 ,要把某一层的含义数据 取出来时, 使用自连接 ! 

把一张表, 看作多张表进行查询

s_emp表:   

     员工的id   

     领导的编号

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

    我们可以去找到哪些人是领导!

    领导和员工的关联关系:  领导的id 是 普通员工的manager_id

    将员工表格 看作两个表格 : 员工表e 和 管理员表m ,这两个表的数据是完全相同的.

    我们通过员工的manager_id与领导的id进行关联, 来完成多表查询! 匹配到的m表格中的数据 就是领导的数据: 

    select distinct m.id,m.last_name from s_emp e,s_emp m where e.manager_id=m.id;
    //因为有些领导管理着多个员工, 会被匹配多次 ,需要加入排重字段distinct
    //查询所有的领导id , 来对比观察是否有问题
    select manager_id from s_emp;

    查询结果: 

               ID LAST_NAME
    ---------- -----------
             9 Catchpole
             1 Velasquez
             8 Biri
             2 Ngao
             7 Menchu
             3 Nagayama
             6 Urguhart
            10 Havel
外连接(+)

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

通过在字段后面添加(+) , 来完成外连接操作

格式:     把(+)加载where条件的字段后面 ,  (+)号修饰的字段所在的表的对面表格的数据全部被选中 !

    特点: 内连接匹配不上的数据, 因为外连接要取出, 外连接会通过补足null行来生成结果集

查询s_emp表格, 获取普通员工的信息

select distinct m.last_name,m.id from s_emp e,s_emp m where e.manager_id(+)=m.id and e.manager_id is null;


        e                           m
e.id    e.name  e.m_id      m.id    m.name  m.m_id

2       b       1           1       a       null

//3     c       1           1       a       null

4       d       2           2       b       1

//5     e       2           2       b       1

null    null    null        3       c       1

null    null    null        4       d       2

null    null    null        5       e       2


select m.id,m.name from e,m where e.manager_id is null;
SQL99标准连接 了解

SQL99内连接

    格式
    select 字段 from 表1 inner join 表2 on 连接条件 where 过滤条件;

    -   inner 与 where过滤条件可以忽略不写!

    查询员工last_name与部门的名称:
    oracle方式:
        select last_name,name from s_emp,s_dept where s_emp.dept_id=s_dept.id;
    sql99方式:
        select last_name,name from s_emp inner join s_dept on s_emp.dept_id=s_dept.id;

    查询部门名称 , id 和对应的地区名称 , 并且部门编号大于20

    oracle方式:
        select d.name,d.id,r.name from s_dept d,s_region r where d.region_id=r.id and d.id>20;
     sql99方式:
        select d.name,d.id,r.name from s_dept d inner join s_region r on d.region_id=r.id where d.id>20;
SQL99中的外连接

左外连接
    左边数据一个都不能少 , 就是oralce中把(+)放在了右边!
    格式: select 字段 from 表1 left [outer] join 表2 on 连接条件 where 过滤条件;


右外连接
    右边数据一个都不能少 , 就是oralce中把(+)放在了左边!
    格式: select 字段 from 表1 right [outer] join 表2 on 连接条件 where 过滤条件;


查询不是领导的id与last_name
    oracle:
    select distinct m.id,m.last_name from s_emp e,s_emp m where e.manager_id(+)=m.id and e.manager_id is null;

    sql99:
    select distinct m.id,m.last_name from s_emp e right outer join s_emp m on e.manager_id=m.id where e.manager_id is null;

全外连接
练习:

1.  显示员工的last_name和对应的部门名称, 要求, 把不存在部门编号的员工也给查询到 :

    题1的前置条件: 
        公司的业务需要 , 把id为25的员工 分配到一个新的项目组中, 部门名称待定!

        update s_emp set dept_id=null where id=25;
        commit;


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

    1.  s_dept表中的 name
    2.  s_region表中的name

    题2的前置条件: 

        公司业务需要, 增加了新的部门, 但是还没确定办公地点 !

        insert into s_dept values(250,'zhiqiang1',null);
        insert into s_dept values(251,'zhiqiang2',null);
        commit;

3.  显示每个员工的工资 和 对应的工资级别 , 超出工资级别范围的 也要显示出来

    工资表: salgrade 


    老板觉得自己工资太低了,  都不够每天泡个脚的 , 给自己涨了工资 涨到了66666, 
    给自己的小秘书涨到了8888

    update s_emp set salary=66666 where id=1;
    update s_emp set salary=8888 where id=24;
    commit;


    在进行外连接时, 如果进行了between (区间)进行比较 , 区间的两边都要添加(+)


    between losal(+) and hisal(+);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值