Oracle基础-内置函数篇

内容简介

对Oracle数据库中常用的数值函数,日期函数,字符串函数,以及聚合函数进行了介绍,所涉及的表为scott用户下的empdept表。

数值函数

四舍五入函数

--1)小数点后取舍   
select round(5555.5555,2)  from dual;                                      -- 返回5555.56                    
select round(5555.5555)    from dual;                                      -- 返回5556
select round(-5555.5555,2) from dual;                                      -- 返回-5555.56                    
select round(-5555.5555)   from dual;                                      -- 返回-5556
 
--2)小数点前取舍   
select round(5555.5555,-2) from dual;                                      -- 返回5600
select round(5555.5555,-6) from dual;                                      -- 返回0
select round(-5555.5555,-2) from dual;                                     -- 返回-5600
select round(-5555.5555,-6) from dual;                                     -- 返回0

取整函数

--1)正无穷方向取整
select ceil(1.5)  from dual;                                               -- 返回2
select ceil(-1.5) from dual;                                               -- 返回-1
--2)负无穷方向取整
select floor(1.5) from dual;                                               -- 返回1
select floor(-1.5)from dual;                                               -- 返回-2

截取数字

-- 截取,1位小数,默认截取整数
select trunc(15.79,1) from dual;

正负号函数

select sign(100),sign(-100),sign(0) from dual;                             -- 正值返回1,负值返回-1,0返回0

绝对值函数

select abs(2.5) from dual;
select abs(-2.5)from dual;                                                 --返回2.5

取余函数

select mod(5,2) from dual;                                                 --5%2为1

幂函数

select power(3,2) from dual;                                               --3的2次方

select exp(1) from dual;                                     -- 自然对数e的0次幂,1次幂,2次幂

对数函数

select log(2,4) from dual;                                                 -- log以2为底,4的对数

select ln(2.714) from dual;                                                -- log以e为底,2.714的对数

平方根函数

select sqrt(4) from dual;

截取任意精度

--截取任意精度  正数:小数点后保留位数   负数:小数点前元整位数    0或缺省:截取整数
 select trunc(12345.6789,2),trunc(12345.6789,-2),trunc(12345.6789)  from dual;

随机数

-- [0,1)之间的随机数
select dbms_random.value from dual;                                        -- [0,1)范围

-- 指定范围的随机数小数
select dbms_random.value(0,100) from dual;

-- 指定范围的随机整数
select trunc(dbms_random.value(0,100)) from dual ;

-- 正态分布的随机数
select dbms_random.normal from dual ;

中位数,标准差,方差

median() 中位数
stddev() 标准差
variance() 方差

select median(sal) ,stddev(sal) , variance(sal) from emp;

三角函数

-- 三角函数(弧度制)
select sin(3.1515926/2) from dual;
select cos(3.1515926/2) from dual;
select tan(3.1515926/2) from dual;
select sinh(2.714) from dual;
select cosh(2.714) from dual;
select tanh(2.714) from dual;
select asin(0.5) from dual;
select acos(0.5) from dual;
select atan(0.5) from dual;

数字字符转换函数

--数字转为字符
select to_char(12345.6789,'999999999999999')from dual;                      --显示整数位,格式化不足则会显示##,位数太多前面空格填充
 
select to_char(12345.6789,'99999.99')from dual;                             --小数点后保留2位,四舍五入保存
 
select trim(to_char(12345.6789,'999,999,999,999.99')) from dual;            --显示千位符,并保留两位小数       
 
select to_char(12345.6789,'$99,999.99')from dual;                           --显示美元符号
 
select to_char(12345.6789,'s99999.99')from dual;                            --显示正号
--将字符转为数字
select to_number('$12,345.67','$99,999.99') from dual;                      --去掉美元符号,千分号

字符函数

ASCII转换函数

--查看字母的ASCII值
select ascii('A'),ascii(1),ascii('你') from dual;                           -- 字母和数字智能填一个,多填以第一个为主

--将ASCII值转为字符
select chr(65),chr(49),chr(50403) from dual;                               -- 注意数字的位数

大小写转换函数

--小写转大写
select upper ('hello') from dual;                                          --注意字符串需要加引号
 
--大写转小写
select lower ('HELLO') from dual;
 
--首字母大写
select initcap('good') from dual;

字符索引函数

单行函数,查找字符串索引位置,索引从1开始.

-- 存在返回下角标
select instr('a b c d e' , 'a') from dual;
-- 返回下角标
select instr('a b c d e' , 'c') from dual;
-- 不存在,返回0
select instr('a b c d e' , 'f') from dual;

字符串截取函数

--1)从开始索引到最后
select substr('string',3) from dual;                                       --返回 ring ,在字符串位置开始处为1
 
--2)从开始索引获取后面指定长度的元素
select substr('string',3,2) from dual;                                     --返回 ri
 
--3)从结尾索引到最后
select substr('string',-3) from dual;                                      --返回 ing
 
--4)从结尾索引获取到后面指定长度的元素
select substr('string',-3,2)from dual;                                     --返回 in
 
--!)从结尾索引获取到前面指定长度的元素
select substr('string',-3,-2)from dual;                                    --没有这个用法

字符串长度函数

--获取字符串长度
select length('string') from dual;

--获取字符串byte长度
select lengthb('string') from dual;

字符串连接函数

--字符串链接
select concat('hello','word') from dual;

字符串分隔函数

--字符串分隔函数
select * from table(split('Hello,World',','));                             --将字符串根据,逗号分隔

字符串裁剪函数

--去除子字符串,默认去除空格
--1)从两则去除
select trim('a'from'abcd') from dual;                                      --无效,只能在开头去除
select trim('a'from'abba') from dual;

--2)从左侧去除
select ltrim ('abba' , 'a' ) from dual;
 
--3)从右侧去除       
select rtrim ('abba' , 'a' ) from dual;                                    --注意顺序
 
--4)去除字符串中两侧的空格
select trim(' a b c ') from dual;                                          -- 不传参时,为去除两侧空格

字符串填充函数

--填补字符   被填充字符  填充后总长度(若小于当前长度则表示截取指定长度)  填充的字符,默认为空格填充
--1)从左侧填充
select lpad('hello',8,'*') from dual;                                      --将hello左*填充至8位

--2)从右侧填充
select rpad('hello',8,'*') from dual;

--替换字符串
select replace('abcd','ab','ABC') from dual;                               --替换的个数并不受到影响
select replace('abcd','a') from dual;                                      --不指定替换为什么,默认为删除指定字符

金融格式化

-- 金融格式化
select to_char(123456789.99 , 'FM999,999,999,999,999.99') from dual;
-- 带有补零的
select to_char(123456789.99 , 'FM000,000,000,000,000.00') from dual;
select to_char(123456789.99 , 'FM999,999,999,999,990.00') from dual;
-- 货币显示,本地,美元
select to_char(123456789.99 , 'L999,999,999,999,999.99') from dual;
select to_char(123456789.99 , '$999,999,999,999,999.99') from dual;

日期函数

设置系统默认显示日期格式

alter session set nls_date_format = 'yyyy-MM-dd hh24:mi:ss';
select sysdate from dual;

获取当前时间

--获取系统日期  年/月/日 时:分:秒
select sysdate from dual;                                                  

--获取会话的时间的时间戳
select localtimestamp from dual;

--获取会话在当前时区的时间戳
select current_timestamp from dual;

--获取当前数据库时区,会话时区
select dbtimezone ,sessiontimezone from dual;

日期增减

-- 增加天数
select (sysdate+1) from dual;
-- 增加小时
select (sysdate+1/24) from dual;
-- 增加分钟
select (sysdate+1/24/60) from dual;
-- 增加秒钟
select (sysdate+1/24/60/60) from dual;

月份增减函数

--增减月数
select add_months(sysdate,2) from dual;                                    --当前时间中月份加2
select add_months(sysdate,-2) from dual;                                   --当前时间中月份减2

获取下一周日期

--获取下一个星期几的日期
select next_day(sysdate,'星期日') from dual;                               --格式必须为星期几(根据系统环境)

获取本月最后一天

--获取这个月的最后一天
select last_day(sysdate) from dual;

获取月份间隔

--获取两个日期之间相隔的月数                                                 --前一个月份减去后一个月份,为小数
--注意格式,字符串自动转为日期的格式为: 日数-X月-年数
select months_between(sysdate,to_date('2015-05-15','yyyy-mm-dd'))from dual;
select months_between(to_date('2015-05-15','yyyy-mm-dd'),sysdate)from dual;
select months_between('1-10月-14','1-10月-15') from dual;        

四舍五入日期

--四舍五入日期
select round(sysdate) from dual;                                            --获取0点最近的天
select round(sysdate,'day') from dual;                                      --获取最近的星期天
select round(sysdate,'month') from dual;                                    --获取最近的月初
select round(sysdate,'q') from dual;                                        --获取最近的季度
select round(sysdate,'year') from dual;	

随机日期

-- 随机日期
select to_char(sysdate,'J') from dual ;                                    -- 将日期转为日期整数
select to_date(2457947+trunc(dbms_random.value(0,365)),'J') from dual ;

截取日期

-- 截取日期到年度开始
select trunc(sysdate,'YYYY') from dual;
-- 截取日期到月份开始
select trunc(sysdate,'MM') from dual;
-- 截取到本周的开始
select trunc(sysdate,'day')+1 from dual;
-- 截取日期到天开始
select trunc(sysdate,'DD') from dual;
select trunc(sysdate) from dual;
-- 截取日期到小时开始
select trunc(sysdate,'HH') from dual;
select trunc(sysdate,'HH24') from dual;
-- 截取日期到分钟开始
select trunc(sysdate,'MI') from dual;

获取日期信息

--获取日期中的年/月/日
select extract (year from sysdate) from dual;                               --获取年
select extract (month from sysdate) from dual;                              --获取月
select extract (day from sysdate) from dual;                                --获取日
select extract (hour from localtimestamp) from dual;                        --获取时,仅限时间戳类型
select extract (minute from localtimestamp) from dual;                      --获取分,仅限时间戳类型
select extract (second from localtimestamp) from dual;                      --获取秒,仅限时间戳类型

示例,获取两个日期间的间隔分钟

-- 两个日期分钟间隔 , 不连续
select 
  extract (MINUTE from to_timestamp('2018-1-5 00:10:00' ,'yyyy-MM-dd hh24:mi:ss') 
                       - to_timestamp('2018-1-1 00:00:00' ,'yyyy-MM-dd hh24:mi:ss'))
from dual;

字符串日期转换

--字符转为日期
select to_date('2015-1-1','yyyy-mm-dd') from dual;                          --以系统日期格式保存,取出时任然需要格式转化

--日期转换为字符
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;                  --获取全部的日期,时刻 格式
select to_char(sysdate,'yyyy-mm-dd') from dual;                             --获取日期
select to_char(sysdate,'mm-dd') from dual;                                  --获取感兴趣的部分        
select to_char(sysdate,'day') from dual;                                    --获得星期
select to_char(sysdate,'AM') from dual;                                     --获得上午|下午时间段
select to_char(sysdate,'ddd') from dual;                                    --获得本年的第几天
select to_char(sysdate,'dl') from dual;                                     --获得日期和星期          2017年7月12日 星期三
select to_char(sysdate,'ds') from dual;                                     --获得日期               2017-07-12
select to_char(sysdate,'iw') from dual;                                     --获得本年度第几周
select to_char(sysdate,'q') from dual;                                      --获得本年度第几季度
select to_char(sysdate,'j') from dual;  
select to_char(sysdate) from dual;                                          --默认格式: 日-X月-年      14-9月-16

聚合函数

平均值函数

--平均值
select avg(sal) from emp;

求和函数

--总值
select sum(sal)  from emp;

极大值函数

--极大值
select max(sal) from emp;

极小值函数

--极小值                    
select min(sal) from emp;                                                   -- 不包括空,空值过滤

标准差函数

--标准差
select stddev(sal) from emp;
select stddev(distinct sal) from emp;

方差函数

--方差
select variance(sal) from emp;
select variance(distinct sal) from emp;

统计函数

count一定会有的返回值

--计数
select count(*) from emp;
select count(distinct emp.job) from emp;                                    -- 必须指定具体的字段,去重输出
select count(*) , count(empno) , count(comm) , count(distinct job) from emp;

位置函数

相对位置函数

cume_dist() 函数,计算一行在分区的相对位置,例如,分区有五条记录,则按照 1 , 0.8 , 0.6, 0.4 , 0.2进行划分

select deptno , ename, sal,
    cume_dist() over(partition by deptno order by sal) cume
from emp

等分函数

ntile()函数针对数据分区中的有序集合进行划分,类似于分成等份

select deptno , sal, 
  sum(sal) over (partition by deptno order by sal) dept_sum_sal,
  ntile(3) over (partition by deptno order by sal) dept_ntile_sal_3,
  ntile(6) over (partition by deptno order by sal) dept_ntile_sal_6
from emp

比例函数

ratio_to_report() 计算该行所在比例

select deptno , sum(sal),
  ratio_to_report(sum(sal)) over () rate
from emp

分析函数

分许函数的语法如下:

函数名([参数,...]) over (
partition by 子句 字段, ...
[order by 子句 字段, ... [asc | desc | nulls first | nulls last]]
[windowing 子句]);

其中:
over子句: 为分析函数指明一个查询结果集,此语句在select子句之中使用
partition by子句:将一个简单的集合分为N区,而后按照不同的区对数据进行统计
order by子句:指明数据在区中的排列方式
nulls first | nulls last 返回数据列中,包含NULL值是出现在排序序列前还是尾
windowing子句:给出变化固定的数据窗口的方法,分析函数将对此数据进行操作

常见组合

第一种 函数名称(参数,…) over (partition by 子句 , order by 子句, windowing子句);
第二种 函数名称(参数,…) over (partition by 子句 , order by 子句);
第三种 函数名称(参数,…) over (partition by 子句);
第四种 函数名称(参数,…) over ( order by 子句, windowing子句);
第五种 函数名称(参数,…) over ( order by 子句 );
第六种 函数名称(参数,…) over ( );

over子句

-- 根据查询结果,进行求和
select deptno , ename , sal ,
  sum(sal) over () sum_sal
from emp;
-- 根据查询结果,随后进行分区求和
select deptno , ename , sal ,
  sum(sal) over (partition by deptno) sum_sal
from emp;
-- 根据查询结果,随后进行多条件分区,求和
select deptno , ename , sal , job ,
  sum(sal) over (partition by deptno , job) sum_sal
from emp;
-- 根据查询结果,随后进行多条件分区,求和,随后排序 rank()产生序列,有名次并列
select deptno , ename , sal ,
  rank() over (partition by deptno  order by sal desc , ename asc) rk
from emp;
-- nulls first|last 当为空时,null所在记录排在最前面或者最后面,默认空放在第一位
select deptno , ename , sal , comm , 
  rank() over (order by comm desc nulls last) rk,
  sum(sal) over (order by comm desc nulls last) sum_sal
from emp;

window 分窗子句

分窗子句主要是用于定义一个变化的或者固定的数据窗口方法,主要用于定义分析函数在操作行的集合

分窗子句有两种实现方式:

  • 实现一: 值域窗(range window),逻辑便宜.当前分区之中前行的N行到当前行的记录集
  • 实现二: 行窗(rows window),物理便宜.以排序的结果顺序计算偏移当前行的起始行记录集

如果想要指定range或rows的偏移量,则可以采用如下的几种排序列:

range | rows 数字 preceding
range | rows between unbounded preceding and current row
range | rows between current row and unbounded following

以上几种排序之中包含的概念:
preceding 主要设置一个偏移量,可以为数字或者为其他
between…and… 偏移量范围
unbounded preceding 不限制偏移量大小
current row 当前行
following 如果不写,表示使用N行与当前行指定数据比较,如果编写次语句,表示当前行与下N行数据比较

示例

-- 验证range  根据部门进行分区,同时按照部门内工资升序排序,sum_sal对当前行之前的记录,如果不超过300则进行累计求和,否则重新求和
select deptno, ename, sal,
  sum(sal) over (partition by deptno order by sal
                 range 300 preceding) sum_sal
from emp;                 

-- 使用向下匹配,向下求和,注意相同值的匹配
select deptno, ename, sal,
  sum(sal) over (partition by deptno order by sal
                 range between 0 preceding and 300 following) sum_sal
from emp;                 

-- 匹配当前行,没有偏移量进行求和
select deptno, ename, sal,
  sum(sal) over (partition by deptno order by sal
                 range between 0 preceding and current row) sum_sal
from emp;        

-- 不设置边界,不限制偏移量,注意相同值的数据
select deptno, ename, sal,
  sum(sal) over (partition by deptno order by sal
                 range between unbounded preceding and current row) sum_sal
from emp;        

-- 物理偏移,当前行等于前两行的求和
select deptno, ename, sal,
  sum(sal) over (partition by deptno order by sal
                 rows 2 preceding) sum_sal
from emp;

-- 设置查询行的范围,不设置下限,并采用下行比较方式.等于对当前分区内所有薪资求和
select deptno, ename, sal,
  sum(sal) over (partition by deptno order by sal
                 rows between unbounded preceding and unbounded following) sum_sal
from emp;

分区统计函数

用于统计分区后各区的数据,常用语法

sum([distinct | all] 表达式)         计算分区中的数据累加和
min([distinct | all] 表达式)         查找分区中的最小值
max([distinct | all] 表达式)         查找分区中的最大值
avg([distinct | all] 表达式)         计算分区中的数据平均值
count(* | [distinct | all] 表达式)    计算分区中的数据量

示例

--查询雇员为7369的雇员名称,职位,基本工资,部门编号,部门人数,部门平均工资,最低工资,最高工资,总工资
select e.empno, e.ename, e.job, e.sal, e.deptno,
    sum(e.empno) over (partition by e.deptno) dept_emp_count,
    avg(e.sal) over (partition by deptno) dept_sal_ave,
    min(e.sal) over (partition by deptno) dept_sal_min,
    max(e.sal) over (partition by deptno) dept_sal_max,
    sum(e.sal) over (partition by deptno) dept_sal_sum
from emp e
where e.empno = 7369;

--查询员工的编号,姓名,基本工资,部门,此部门的平均工资,最低和最高工资
select e.empno, e.ename, e.sal, d.dname,
    avg(e.sal) over (partition by e.deptno order by e.sal
                     range between unbounded preceding and unbounded following) dept_sal_ave,
    min(e.sal) over (partition by e.deptno order by e.sal
                     range between unbounded preceding and unbounded following) dept_sal_min,
    max(e.sal) over (partition by e.deptno order by e.sal
                     range between unbounded preceding and unbounded following) dept_sal_max,                 
    sum(e.sal) over (partition by e.deptno order by e.sal
                     range between unbounded preceding and unbounded following) dept_sal_sum
from emp e , dept d
where e.deptno = d.deptno

等级函数

多用于生成序列,进行排序展示等操作

方法说明
rank()根据order by子句的排序字段,从分区查询一行数据,按照降序生成序号,同分名次相同,下一名次不存在,出现跳号
dense_rank()根据order by子句的排序字段,从分区查询一行数据,按照降序生成序号,同分名次相同,下一名次顺序排列,不会出现跳号
first取出dense_rank()的第一行数据
last取出dense_rank()的最后一行数据
first_value(列)取出分区的第一个值
last_value(列)取出分区的最后一个值
lag(列名称[,行数字][,默认值])访问分区中指定的前N行记录,如果没有则返回默认值
lead(列名称[,行数字][,默认值])访问分区中指定的后N行记录,如果没有则返回默认值
row_number返回每组中的行号

示例

-- TOP-N 问题,并列,后取消下一名次
select rownum , rank() over (order by sal asc) rank, 
e.* from emp e;
-- 并列,则顺序排序,不出现跳号
select rownum , dense_rank() over (order by sal asc) dense_rank, 
e.* from emp e;

-- 重新生成rownum,避免分组后紊乱,表示分组中当前行
select rownum , row_number() over (order by sal asc) row_number, 
e.* from emp e;

keep语句

keep语句保留满足条件的数据
在使用dense_rank确定后的集合才可以使用first或者last取得集合中的数据
语法为:

分组函数() keep (dense_rank first | last order by 表达式[asc | desc | nulls [first | last]],...) [over() 分区查询]

示例

--first | last 查询每个部门的最高及最低工资
select deptno , 
max(sal) keep (dense_rank first order by sal desc) dept_sal_max,
min(sal) keep (dense_rank last order by sal desc) dept_sal_min
from emp
group by deptno;

首尾函数

over()声明一个数据集合,而利用first_value()或者last_value()函数取得集合中的首行和尾行中的字段值

select deptno , empno , sal,
    -- 查找部门最高工资
    first_value(sal) over (partition by deptno order by sal
                           range between unbounded preceding and unbounded following) sal_first_value,
    last_value(sal) over (partition by deptno order by sal
                           range between unbounded preceding and unbounded following) sal_last_value
from emp

相邻记录

在满足于一定顺序的基础上,对前|后偏移量的数据进行重现
lag(字段,偏移量,默认值) 查找前X行字段数据,没有则返回默认值
lead(字段,偏移量,默认值) 查找后X行字段数据,没有则返回默认值

-- 相邻记录
select deptno, empno , ename, sal,
    lag(sal,2,null) over (partition by deptno order by sal) dept_lag_sal,
    lead(sal,2,null) over (partition by deptno order by sal) dept_lead_sal
from emp
where deptno = 20;

报表函数

cume_dist() 计算一行在分区中的相对位置
ntile(数字) 将一个分区分为"表达式"的散列表示
ratio_to_report(表达式) 改函数计算表达式的值,它给出相对于总数的百分比

-- cume_dist() 函数,计算一行在分区的相对位置,例如,分区有五条记录,则按照 1 , 0.8 , 0.6, 0.4 , 0.2进行划分
select deptno , ename, sal,
    cume_dist() over(partition by deptno order by sal) cume
from emp

-- ntile()函数针对数据分区中的有序集合进行划分,类似于分成= = 份
select deptno , sal, 
  sum(sal) over (partition by deptno order by sal) dept_sum_sal,
  ntile(3) over (partition by deptno order by sal) dept_ntile_sal_3,
  ntile(6) over (partition by deptno order by sal) dept_ntile_sal_6
from emp

-- ratio_to_report() 计算该行所在比例
select deptno , sum(sal),
  ratio_to_report(sum(sal)) over () rate
from emp
group by deptno
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值