1、oracle-单行函数,多行函数,分组统计

oracle 11G 安装文档:https://download.csdn.net/download/u014749668/10639855
oracle 客户端实例配置:https://download.csdn.net/download/u014749668/10639858

1 sqlplus 基本使用

登录
        sqlplus scott/11
        sqlplus sys/密码  as sysdba 
        sqlplus /  as sysdba   --管理员
        sqlplus 用户/密码       --本地登录
        sqlplus 用户/密码@//主机号(ip)/实例名(orcl)
        sqlplus scott/11@//192.168.0.29/orcl

    退出
        exit 、 quit

    启动数据库实例
        startup 
    关闭数据库实例
        shutdown

    开启远程监听服务(不是在sqlplus,而是在shell环境里边)
        lsnrctl start
        lsnrctl status
        lsnrctl stop

    显示当前用户
        show user
    清屏
        host cls

    修改用户密码 
        alter user scott account unlock 
        alter user scott identified by  "新密码"

    显示当前方案、用户有什么表
        select * from tab

    查看表结构
        desc 表名

    修改sqlplus行宽
        set linesize 140;

    修改页高
        set pagesize 50

    使用sqlplus启动的时候就自动设置列宽页高
        写在product\11.2.0\client_1\sqlplus\admin\glogin.sql

DML 数据操作语言
增 insert
删 delete
改 update
查 select
DDL 数据定义语言
create table(创建表)
alter table(修改表)
truncate table(清空表)
drop table(删除表)
create view(视图)
create index(索引)
create sequence(序列)
create synonym(同义词)
DCL数据控制语言
commit(提交)
rollback(回滚)
这里写图片描述

2 简单查询


    select *|列名 [as 别名],列名2... | 表达式
        from 表名
        where cond

    1 查询emp表的所有数据
        select * from emp;

    2 查询员工号,姓名,月薪,奖金,年薪,年收入 并修改列名为中文(返回结果集)
        select empno as "工号", ename "姓名", sal 月薪, 
            comm "奖 金", sal*12 年薪, sal*12+nvl(comm,0) 年收入  
        from emp

        【结论】:null 做任何数值运算都为null

        列的别名使用双引号,如果列名中间有空格不能省略双引号

        【】使用nvl函数,将null变成0 
            nvl(exp,val) -- 如果exp为空 那么就返回val

    3 查看员工表所有部门编号并去除重复
        使用【distinct】 去重
        select distinct deptno from emp
        结论:distinct 去重,是去重除返回结果集重复的行

    4 计算表达式3+2  =5
        oracle提供了一个虚表,用来计算表达式——dual

3 单条件查询


    1 查询10号部门的员工信息
        select * from emp where deptno = 10

    2 查询KING的信息
        KING
        select * from emp where ename = 'king'  --查不到,大小写敏感
        select * from emp where ename = 'KING'  
        【什么时候用单引号,什么时候用双引号】:
            数据里边都用单引号,双引号一般用在数据库对象名(表名、列名、密码)

    3 查询薪水不等于1250的员工信息
        select * from emp where sal <> 1250


    4 查询入职日期为19811117日的员工信息
        涉及到日期数据的判断
        select * from v$nls_parameters;  查看环境变量  date_format 控制当前环境时间类型显示格式
        alter session set nls_date_format =  'yyyy-mm-dd'  修改日期格式
        select * from emp where hiredate = '1981-11-17'

4 多条件查询


    与 &&  and
    或 ||  or
    非  !  not

    1 查询10号部门中月薪为1300的员工
        select * from emp where deptno =10 and sal = 1300

    2 查询部门号是10或者20的员工信息
        select * from emp where deptno =10 or deptno = 20
        使用in
        select * from emp where deptno in (10,20)   ---集合使用小括号表示

    3 查询部门不是1020的员工信息
        select * from emp where deptno <>10 and deptno <> 20

        select * from emp where deptno not in (10,20)

        如果有NULL 

        select * from emp where deptno not in (10,20,NULL)

        【结论】:null做任何逻辑或者比较运算都为假
            deptno != 10 && deptno != 20 && deptno != NULL  --NULL影响了结果
            deptno =10 || deptno = 20 || deptno = NULL      --NULL 没有影响结果


    4 查询工资介于10002000之间的员工
        select * from emp where sal >= 1000 and sal <= 2000
        使用between and 的方式
        select * from emp where sal between 1000 and 2000

        问题是,【between包不包括边界值 】——包括


    5 查询19812月(含2月)到822月(不含2月)入职的员工信息
        select * from emp where hiredate >= '1981-02-01' and hiredate <'1982-02-01'
        换成between  换成 1982-01-31

    6 查询没有奖金的员工信息
        查询奖金为空
        select * from emp where comm = null  --不能使用比较运算
        【使用is判断nullselect * from emp where comm is null

    7 查询有奖金的员工信息
        select * from emp where comm is not null

5 模糊查询


    【模式匹配】
    where like '模式字符串' escape '转义字符'
    【模式字符串的格式】
        % 表示0或者多个字符
        _ 表示1个字符

    1 查询员工首字母是S的员工信息
        S%
        select * from emp where ename like 'S%'

    2 查询名字是四个字母的员工信息
        select * from emp where ename like '____'

    3 查询姓名带下划线的员工信息
        select * from emp where ename like '%\_%'  --反斜杠不是转义


        sql里边本来就不提供默认的转义字符,要我们自己制定一个 使用【escape】来指定

        select * from emp where ename like '%\_%' escape '\'

6 排序


    按什么排序?   ——  列
    排的什么序?   ——  升序、降序

    select ...
    from ...
    where ...
    order by 列,列2 asc|desc

    1 员工信息按先后入职日期排序
        select * from emp order by hiredate 

    2 员工信息按薪水从大到小排序
        select * from emp order by sal desc

    3 员工信息按部门号和薪水排序
        select * from emp order by deptno,sal
        按照顺序排序deptno,sal

    4 员工信息按部门和薪水排列,降序
        select * from emp order by deptno desc,sal desc

        【结论】:asc|desc 作用在前面那列

    5 员工信息按奖金倒序
        select * from emp order by comm desc
        NULL 会影响排序
        select * from emp order by comm desc nulls last

    6 员工信息按第2列排序
        select * from emp order by 2

        结论:按照返回结果集第几列来排序,而不是表的第几列

    7 员工信息按别名排序
        select enmno , sal "月薪" from emp order by "月薪";

        可以根据别名进行排序

单行函数

(1) 字符函数


    lower  —— 小写
    upper   —— 大写
    initcap  —— 将字符串首每个单词字母变成大写

        函数名(表达式)

    concat —— 字符串拼接
        concat(str1,str2)   ——只支持两个参数
        如果字符串过多,拼接推荐用 ||
        select 'hello ' || 'world '|| '1234' || 123 from dual;  --123 做了隐式转换
    substr —— 取子串
        substr(str , pos , len)  --在str里边第pos个字符取子串,长度是len,len可以省略
        pos 可以是负数,相当于从字符串后边往前面数
        select substr('hello world',-3 ) from dual;   --rld

    instr —— 判断某个字符串在另一个字符串的哪个位置
        instr (str , substr )   --如果找不到,就返回0,找到则返回向相应位置(第几个字符)

    lpad,rpad —— 左填充,右填充
        lpad ( str , len , char) -- 往str左边填充char字符到len长度
        select lpad('hello', 10 , '#') from dual;
        select lpad('hello', 3 , '#') from dual;   --如果字符串长度比len长,就截取

    trim —— 去除两边空格 
        select trim ( '     Hello world   ') from dual;
        select trim ( 'H' from 'Hello worldH') from dual;   --去除两边的H

    replace —— 字符串替换
        replac(str , substr , replaceString) --从str里边找到substr,替换成 replaceString

(2) 数值函数


    round   ——  四舍五入
    trunc   ——  截取
    ceilfloor  —— 向上取整、向下取整
    mod   —— % 取模
    select  round(45.926) 四舍五入,
            round(45.926,1) 四舍五入2,
            trunc(45.926) 截取,
            trunc(45.926,1) 截取2,
            ceil(45.926) 向上取整,
            floor(45.926) 向下取整,
            mod(1000,600) 取模
        from dual
          四舍五入  四舍五入2       截取      截取2   向上取整   向下取整       取模
        ---------- ---------- ---------- ---------- ---------- ---------- ----------
                46       45.9         45       45.9         46         45        400

(3) 转换函数
这里写图片描述


    数字转字符串 to_char

        to_char(数字)
        to_char(数字,格式字符串)

        将薪水转化为本地货币字符型
        select to_char(sal,'L9999') from emp;    -L 代表本地货币符号 ,9代表一位数


    字符串转数字 to_number
        select to_number('1234') from dual;

        select to_number('¥950','L9999') from dual;

        用什么格式转到数字类型的,就用什么格式转回去字符串

    日期转字符串 to_char
        hiredate 转字符串
        select hiredate ,to_char(hiredate , 'dd-mm-yyyy day')  from emp;
    字符串转日期 to_date
        select to_date( '17-12-1980 星期三' , 'dd-mm-yyyy day') from dual;

(4) 日期函数


    sysdate  --获取当前系统的时间
        select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
        sysdate 不仅包含日期,还包含时间

        1 显示昨天、今天、明天
            日期类型的计算 +1 -1  单位是天
            select sysdate -1 昨天 , sysdate 今天 , sysdate +1 明天 from dual;

        2 计算员工工龄,按照日、周、月、年显示
            日期相减,得到两个日期相隔多少天
            select  ename ,hiredate,
                    sysdate- hiredate "天",
                    (sysdate - hiredate) / 7 "周",
                    (sysdate - hiredate) / 30 "月",
                    (sysdate - hiredate) / 365 "年"
                from emp


    months_between
        months_between(date1 , date2 ) --算出两个时间相差多少个月——精确值

                select  ename ,hiredate,
                    (sysdate - hiredate) / 30 "月",
                    months_between(sysdate,hiredate) "精确月"
                from emp
    add_months
        add_months(date, n) 在date上添加n个月
        计算明年今日
            select add_months(sysdate,12) "明年今日" from dual;
    last_day
        last_day(date)  --返回date 所在 月的最后一天
        select last_day(sysdate) from dual;

    next_day
        next_day(sysdate,'星期三')  -- 返回下一个星期几是哪一天
        select next_day(sysdate,'星期三') from dual;

(5) 通用函数


    nvl  
        nvl(exp,retval) 如果exp是空,就返回retval,否则返回exp

    nvl2
        nvl2(exp , val1 , val2)   如果exp不为空 ,返回val1, 否则返回val2
        查询员工信息,有奖金就显示'有奖金',没奖金就显示'没奖金'

(6) 条件语句


    case when then else end   —— 标准 SQL 提供的
    decode    ——oracle提供的一个函数
    总裁决定给大家涨工资,主管涨1000,销售涨500,其他涨200
        switch(job)
        {
            case 'MANAGER' : sal + 1000; break;
            case 'SALESMAN' : sal + 500; break;
            default : sal + 200; break;
        }

        case(job)
            when 'MANAGER' then sal + 1000
            when 'SALESMAN' then sal + 500
            else sal + 200
        end

        select ename , job , sal 涨前工资 ,
                case(job)
                    when 'MANAGER' then sal + 1000
                    when 'SALESMAN' then sal + 500
                    else sal + 200
                end  "涨后工资"
            from emp

        使用decode
            decode(exp , val1 ,val2 ,val3 , val4 ..... , defaultVal);
                如果exp 是 val1 返回val2 , 否则继续判断 
                    是val3 返回 val4   ....
                    如果都不是,就返回defaultVal

多行计算函数

(1)统计函数


    遍历表的各行数据,统计完后再返回结果
    sum
        1 求员工工资总和
            select sum(sal) from emp;
    count
        1 求员工数量,有奖金的员工数
            select count(*) 员工数量, count(comm) from emp
            count(*) 只要一行有数据就统计
            count(comm) 只有comm 不是null才统计
            结论:
                【】NULL不会参与统计函数的统计

        2 求工作岗位数量  统计去重
            select count(distinct job) from emp;

    max/min
        求员工最高工资和最低工资

    avg
        求员工平均工资
            select avg(sal) from emp;
        求员工平均奖金(三种方式)
            select avg(comm) ,sum(comm)/count(*) ,sum(comm)/count(comm)  from emp;

分组统计

select…
from…
where…
group by 列1,列2…,根据某列,多列进行分组
having cond 分组完成在判断
order by 列1,列2…,asc | desc


    select ...
    from ...
    where ...
    group by1,列2....    --根据某列、多列进行分组
    having cond
    order by

    1 查询各部门平均工资
        select deptno , avg(sal)
        from emp
        group by deptno

        【结论】:统计函数在有分组的情况下,统计的就是每个分组里边多行数据
            没有分组的情况下,就是统计全表
        在select 中出现的列,必须在group by中出现 ,除了统计函数

    2 查询平均薪水大于2000的部门

        select deptno , avg(sal)
        from emp
        where avg(sal) > 2000
        group by deptno
        第 3 行出现错误:
        ORA-00934: 此处不允许使用分组函数

        where 里边不允许使用分组函数进行判断 
        使用having
        select deptno , avg(sal)
        from emp
        group by deptno
        having avg(sal) > 2000

    310号部门员工的平均薪水
        select deptno  , avg(sal)
        from emp
        where deptno = 10
        group by deptno

        having

        select deptno  , avg(sal)
        from emp
        group by deptno
        having deptno = 10

    4 havingwhere的区别
        select ..
        from emp
        where cond
        group ...
        havin cond
        order by ...

        where能做的having也能做,where不能做的having也能做
        结论:能用where就别用having

        1from 的表 emp 拿出数据
        2 逐行筛选,通过where条件来筛选 , 结果集1
        3 分组,并且计算统计函数 ,结果集2
        4 再进行筛选,having的条件,通过having的条件就留下,得到结果集3
        5 排序 得到结果集

        如果一开始不通过where筛选,后边计算量大

猜你喜欢

转载自blog.csdn.net/u014749668/article/details/82287339