Oracle SQL常用内置系统函数总结

Oracle数据库  内置系统函数主要分为以下类别:数学函数、字符串函数、日期函数、转换函数、聚合函数、分析聚合函数

一、数学函数 ------------返回数字

      abs(n):返回数字n的绝对值
      ceil(n)
:返回>=数字n的最小整数
      floor(n)
:返回<=数字n的最大整数
      round(n,[m])
:做四舍五入运算,如果m缺省则四舍五入到整数位
                               
m<0,四舍五入到小数点的前m位,m>0四舍五入到小数点的后m位
      trunc(n,[m])
:截取数字,如果m缺省则将小数位截去
                             
 m<0,截取到小数点的前m位,m>0截取到小数点的后m位

--Demo:abs()、ceil()、floor()、trunc()  
SELECT abs(-2.3),  
       ceil(-2.6),ceil(2.6),  
       floor(-2.6),floor(2.6),  
       round(-666.588),round(-666.588,2),round(-666.588,-2),  
       trunc(-666.588),trunc(-666.588,2),trunc(-666.588,-2)  
FROM dual;

运算结果

1  ABS(-2.3) CEIL(-2.6)  CEIL(2.6) FLOOR(-2.6) FLOOR(2.6) ROUND(-666.588) ROUND(-666.588,2) ROUND(-666.588,-2) TRUNC(-666.588) TRUNC(-666.588,2) TRUNC(-666.588,-2)
2 ---------- ---------- ---------- ----------- ---------- --------------- ----------------- ------------------ --------------- ----------------- ------------------
3        2.3         -2          3          -3          2            -667           -666.59               -700            -666           -666.58               -600
 

       sqrt(x):返回数字x(x必须大于0)的平方根
       power(x,y):返回数字x的y次幂,底数x和指数y都可以是任意数字,但是如果底数x为负数则指数y必须为正数
       exp(x):返回常量e(2.71828183....)的x次幂
       ln(x):返回数字x(x必须大于0)的自然对数
       log(x,y):返回以x为底(除0及1的正整数)m的(任何正整数)对数
       mod(x,y):返回x除以y的余数,如果数字m=0则返回n

 --demo:sqrt(),power(),exp(),ln(),log(),mod()  
 SELECT sqrt(4),power(2,3),exp(1),ln(10),log(2,8),mod(5,2)  
 FROM dual

运算结果

1    SQRT(4) POWER(2,3)     EXP(1)     LN(10)   LOG(2,8)   MOD(5,2)
2 ---------- ---------- ---------- ---------- ---------- ----------
3          2          8 2.71828182 2.30258509          3          1

       cos(n):返回数字n(弧度单位表示的角度值)的余弦值
       cosh(n):返回数字n的双曲余弦值
       acos(n):返回数字n的反余弦值,求的结果单位为弧度,n的范围为 -1 < n < 1
       sin(n):返回数字n(弧度单位表示的角度值)的正弦值
       sinh(n,m):返回数字n的双曲正弦值
       asin(n,m):返回数字n的反正弦值,求的结果单位为弧度,n的范围为 -1 < n < 1
       tan(n):返回数字n(弧度表示的角度值)的正切值
       tanh(n):返回数字n的双曲正切值
       atan(n):返回数字n的反正切值,求的结果单位为弧度,n的范围任意数值
       atan(n,m):返回数字n/m的反正切值,求的结果单位为弧度,你可以为任意数值,m不可为0

1 --demo:cos(),cosh(),acos(),sin(),sinh(),asin(),tan(),tanh(),atan(),atan()  
2 SELECT cos(0.5),cosh(2),acos(1),  
3        sin(0.5),sinh(2),asin(0),  
4        tan(0.5),tanh(2),atan(8),atan(16/2)  
5  FROM dual

运算结果

1   COS(0.5)    COSH(2)    ACOS(1)   SIN(0.5)    SINH(2)    ASIN(0)   TAN(0.5)    TANH(2)    ATAN(8) ATAN(16/2)
2 ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
3 0.87758256 3.76219569          0 0.47942553 3.62686040          0 0.54630248 0.96402758 1.44644133 1.44644133

二、字符串函数 ------------返回字符值
      ascii(n):返回字符c的ascii值
      chr(n):将ascii值转换为对应的字符
      initcap(s):将字符串s所有的单词(单词是用.空格或给字母数字字符由空格,控制字符,标点符号进行分隔)的首字母大写,其余小写
      lower(s):将字符串s中所有的字符转换为小写
      upper(s):将字符串s中所有的字符转换为大写
      concat(s1,s2):将字符串s2连接在s1后面,等同于操作符||
      length(s):将返回字串s的长度,返回的长度包括其中的所有空格(尾部空格也算);如果s为null,则返回null 

1 --ascii(),chr(),concat(),initcap(), lower(),upper(), length(),
2 SELECT ascii('A'),chr(65),concat('Hello','World'),  
3        initcap('hello woRld'),  
4        lower('HeLLo woRld'),upper('HeLLo woRld'),  
5        length('HeLLo woRld'),length('天下英雄出我辈')  
6   FROM dual 

运算结果

1 ASCII('A') CHR(65) CONCAT('HELLO','WORLD') INITCAP('HELLOWORLD') LOWER('HELLOWORLD') UPPER('HELLOWORLD') LENGTH('HELLOWORLD')
2 ---------- ------- ----------------------- --------------------- ------------------- ------------------- --------------------
3         65 A       HelloWorld              Hello World           hello world         HELLO WORLD                           11

       lpad(str1,n,str2):在字串str1的左端填充字串str2,直至填充后的str1的总长度为n

                                如果不指定str2则默认为空格

                                如果s1的长度>n,则直接返回s1左端的n个字符

       rpad(str1,n,str2):在字串str1的右端填充字串str2,直至填充后的str1的总长度为n

                                如果不指定str2则默认为空格

                                如果str1的长度>n,则直接返回str1左端的n个字符

1 --demo:lpad、rpad  
2 SELECT lpad('a',10,'8'),lpad('SnnnnnnnnR',6,'8'),  
3        rpad('a',10,'8'),rpad('SnnnnnnnnR',6,'8')  
4    FROM dual 

运算结果

1 LPAD('A',10,'8') LPAD('SNNNNNNNNR',6,'8') RPAD('A',10,'8') RPAD('SNNNNNNNNR',6,'8')
2 ---------------- ------------------------ ---------------- ------------------------
3 888888888a       Snnnnn                   a888888888       Snnnnn

      instr(str1,str2,n,m):取得子串str2在字串str1中的位置

                                    n表示在str1中开始搜索的位置,m表示字串str2出现的次数

                                    如果n为负数,则表示从尾部开始搜索,n与m默认为1

  substr(str, m, n) : 字符串截取函数,str需要截取的字符串,从str的m开始,截取长度为n的子串
                      m截取字符串的开始位置(注当m等于0或1时,都是从第一位开始截取),m>0表示从头开始搜索,m<0表示从尾开始,
                      n要截取的字符串的长度。

  substr(str, m) : 字符串截取函数,从第m个字符开始截取后面所有的字符串,str需要截取的字符串,

          m截取字符串的开始位置(注当m等于0或1时,都是从第一位开始截取)。

SQL> select substr('helloworld',5),substr('helloworld',1) from dual;
SUBSTR('HELLOWORLD',5) SUBSTR('HELLOWORLD',1)
---------------------- ----------------------
oworld                 helloworld
1 -- instr(), substr()
2 SELECT instr('888arrayarray','array',1,1) ,instr('888arrayarray','array',1,2),  
3        instr('888arrayarray','array',-1,1),instr('888arrayarray','array',-1,2),
4        substr('纵横天下',1,2),substr('array',-4,3)
5 FROM dual

运算结果:

1 INSTR('888ARRAYARRAY','ARRAY', INSTR('888ARRAYARRAY','ARRAY', INSTR('888ARRAYARRAY','ARRAY', INSTR('888ARRAYARRAY','ARRAY',
2 ------------------------------ ------------------------------ ------------------------------ ------------------------------
3                              4                              9                              9                              4

         ltrim(s1,str):从左端开始逐一取得字串s1左端包含的str中的任何字符

                                当遇到不是str中的字符是,则结束并返回剩余结果

         rtrim(s1,str):从右端开始逐一取得字串s1右端包含的str中的任何字符

                                当遇到不是str中的字符是,则结束并返回剩余结果

         trim(c FROM str):从字串str的头部、尾部、或两端截去字符c(c只能够是一个字符)

                                      当遇到不是str中的字符是,则结束并返回剩余结果

1 SELECT ltrim('terry','t'),ltrim('terry','ter'),ltrim('terry','e'),  
2         rtrim('terry','y'),rtrim('terry','ry'),rtrim('terry','yre'),  
3         trim('e' from 'terry'),trim('t' from 'terry'),trim('y' from 'terryy')  
4 FROM dual 

运算结果:

1 LTRIM('TERRY','T') LTRIM('TERRY','TER') LTRIM('TERRY','E') RTRIM('TERRY','Y') RTRIM('TERRY','RY') RTRIM('TERRY','YRE') TRIM('E'FROM'TERRY') TRIM('T'FROM'TERRY') TRIM('Y'FROM'TERRYY')
2 ------------------ -------------------- ------------------ ------------------ ------------------- -------------------- -------------------- -------------------- ---------------------
3 erry               y                    terry              terr               te                  t                    terry                erry                 terr

      replace(s1,s2,s3):将s1字串中的子串s2用s3替代,如果s2为null则返回原来的字串s1

                                        注意:如果s3为null,则会去掉子串s2

  translate(s1,froms,tos):将字符串s1按照froms和tos的对应关系进行转换

SELECT replace('风清扬_array','风清扬','令狐冲'),replace('风清扬_array','风清扬'),
       translate('aerry','abcdefgxyz','888888666')  
    FROM dual
    
REPLACE('风清扬_ARRAY','风     REPLACE('风清扬_ARRAY','风     TRANSLATE('AERRY','ABCDEFGXYZ'
------------------------------ ------------------------------ ------------------------------
令狐冲_array                   _array                         88rr6

       regexp_substr(s1,pattern,position,occurrence,match_parameter)

                      按照正则表达式pattern从s1字串中的position位置开始

                      截取第occurrence次出现的匹配pattern的字串,matche_parameter为默认匹配的文本

                      position,occurrence,matche_parameter 默认为1,1," "

  regexp_replace(s1,pattern,position,occurrence,match_parameter)

                      正则表达式扩展replace的功能,用于按照特定的表达式pattern的规则替换字串串s1

                      s1指定替换字符串,position指定起始搜索位置

                      occurrence指定替换出现的第n个字符串

                      matche_parameter指定默认匹配操作的文本串

  regexp_like():用正则表达式扩展后的like

  regexp_instr():用正则表达式扩展后的instr

1 SELECT regexp_substr('我的箱[email protected]','[[:lower:]]{1,}+@{1}+[[:alnum:]]{1,}+\.{1}+[[:alpha:]]{1,}'),  
2        regexp_replace('这是什么http://www.space.com.tw/product','http://([[:alnum:]]+\.?){3,4}+[[:print:]]{1,}','www.terry.com')  
3 FROM dual
4 
5 REGEXP_SUBSTR('我的箱HELLOW    REGEXP_REPLACE('这是什么HT
6 ------------------------------ ------------------------------
7 helloword@126.com              这是什么www.terry.com

三、日期函数

   sysdate:返回系统当前日期时间

      systimestamp:返回系统当前日期时间和时区

      current_date:返回当前回话时区所对应的日期和时间

      current_timestamp:返回当前回话时区所对应的日期时间

      localtimestamp:返回当前回话时区所对应的日期时间

      systimestamp:返回系统当前日期时间和时区

      sessiontimezone:返回当前回话所在的时区

      dbtimezone:返回资料库所在的时区

1 SELECT sysdate,systimestamp,current_date,current_timestamp,  
2        localtimestamp,sessiontimezone,dbtimezone  
3 FROM dual
4 YSDATE     SYSTIMESTAMP                            CURRENT_DATE CURRENT_TIMESTAMP                       LOCALTIMESTAMP                 SESSIONTIMEZONE    DBTIMEZONE
5 ----------- -------------------------------------- ------------ --------------------------------------- ------------------------------ ------------------ ----------
6 2017/10/10  10-OCT-17 10.23.03.532728 AM +08:00    2017/10/10 1 10-OCT-17 10.23.03.532742 AM +08:00     10-OCT-17 10.23.03.532742 AM   +08:00             +00:00

      add_months(d,n):返回指定日期d之后(或前)的n个月所对应的日期时间;n>0:之后,n<0:之前

      extract():用于从特定的日期时间值里取出所需要的特定数据(如日期、月份、日、时间等)

      last_day(d):用于返回指定日期所在月份的最后一天

      next_day(d,char):返回指定日期后的一个工作日(由char指定)所对应的日前

      round(d[,fmt]):返回日期时间的四舍五如结果,如果fmt指定年度則7月1日为分界线
                                 如果fmt指定月則16日为分界线,如果fmt指定天則中午12:00为分界线

      trunc(d[,fmt]):用于截断日期时间数据,如果fmt指定年度则结果为本年的1月1日
                                如果fmt指定月则结果为本月1日,如果fmt空则结果为为截取日期时间数据中的日期

1 SELECT sysdate,add_months(sysdate,4),add_months(sysdate,-4),
2        extract(MONTH from sysdate),last_day(sysdate),next_day(sysdate,'sunday'),
3        round(sysdate,'YEAR'),round(sysdate,'MONTH'),round(sysdate,'DAY'),round(sysdate),
4        trunc(sysdate,'YEAR'),trunc(sysdate,'MONTH'),trunc(sysdate,'DAY'),trunc(sysdate)
5    FROM dual

运算结果:

SYSDATE     ADD_MONTHS(SYSDATE,4) ADD_MONTHS(SYSDATE,-4) EXTRACT(MONTHFROMSYSDATE) 
----------- --------------------- ---------------------- ------------------------- 
2017/10/10  2018/2/10 11:29:23    2017/6/10 11:29:23                            10 

LAST_DAY(SYSDATE) NEXT_DAY(SYSDATE,'SUNDAY') ROUND(SYSDATE,'YEAR') ROUND(SYSDATE,'MONTH') ROUND(SYSDATE,'DAY') 
----------------- -------------------------- --------------------- ---------------------- -------------------- 
2017/10/31 11:29: 2017/10/15 11:29:23        2018/1/1              2017/10/1              2017/10/8            

ROUND(SYSDATE) TRUNC(SYSDATE,'YEAR') TRUNC(SYSDATE,'MONTH') TRUNC(SYSDATE,'DAY') TRUNC(SYSDATE)
-------------- --------------------- ---------------------- -------------------- --------------
2017/10/10     2017/1/1              2017/10/1              2017/10/8            2017/10/10

       to_timestamp(s1,fmt):将符合特定日期和时间按格式的字符串转变为 timestamp 类型

   month_between(d1,d2):返回日期d1和d2之间相差的月份数, 如果d1<d2则返回负数,如果d1和d2的天数相同或都是月底则返回整数,

                                              否则oracle以每月31天为准来计算结果的小数部份 

1 select to_timestamp('2015-03-25 11:30:00','YYYY-MM-DD HH24:MI:SS'),
2        sysdate,months_between(sysdate,to_date('2012/06/30','YYYY/MM/DD'))  
3 from dual 

运算结果:

1 TO_TIMESTAMP('2015-03-2511:30:    
2 ----------------------------------
3 25-MAR-15 11.30.00.000000000 AM    
4 
5  SYSDATE     MONTHS_BETWEEN(SYSDATE,TO_DATE  
6  ----------- ------------------------------  
7  2017/10/10                63.3708594683393

四、转换函数

   to_date(s1[,fmt[,nlsparams]]):把一个字符串转换为一个DATE类型的变量. 
              如果指定了fmt,就按fmt格式转换成一个日期类型.
              如果没有指定fmt,使用的就是该会话的缺省日期格式.

  注:在使用Oracle的to_date函数来做日期转换时,很多Java程序员也许会直接的采用'yyyy-MM-dd HH:mm:ss'的格式作为格式进行转换,
     但是在Oracle中会引起错误:'ORA 01810 格式代码出现两次',原因是SQL中不区分大小写,MM和mm被认为是相同的格式代码,
     所以Oracle的SQL采用了mi代替分钟,即: 'yyyy-MM-dd HH24:mi:ss'

1 select to_date('2005-01-01 13:14:20','yyyy-MM-dd HH24:mi:ss') from dual;
2 TO_DATE('2005-01-0113:14:20','yyyy-MM-dd HH24:mi:ss')
3 ----------------------------------------------------
4 2005/1/1 13:14:20

      to_char(num[,fmt]):把日期或数字转换字符串。
                                       如果指定了格式字符串fmt,则按指定格式转换。

--日期转换字符串--
select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss'),
       to_char(sysdate, 'yyyymmddhh24miss'),
       to_char(258.45)
from dual;

运行结果:

TO_CHAR(SYSDATE,'yyyy-mm-dd hh24:mi:ss')
------------------------------ 
2017-10-10 15:53:31 

TO_CHAR(SYSDATE,'yyyymmddhh24miss'),
------------------------------ 
20171010155331                 
 
TO_CHAR(258.45)          
---------------
258.45

       cast(expr AS type_name): 用于将某种数据类型的数据显式转换为另一种数据类型的数据。
                     函数的参数有两部分,源值expr和目标数据类型type_name,中间用AS关键字分隔。

1 select cast('123.4567' AS NUMBER(10,2)),
2        cast('2323' as char(6)),
3        cast(to_date('20110419010101','yyyy-mm-dd hh24:mi:ss') as date) 
4 from dual;

运行结果:

CAST('123.4567'ASNUMBER(10,2)) 
------------------------------ 
                        123.46 

CAST('2323'ASCHAR(6)) 
--------------------- 
2323                  

CAST(TO_DATE('20110419010101','YYYY-MM-DD HH24:MI:SS') AS DATE)
---------------------------------------------------------------
2011/4/19 1:01:01

      numtodsinterval(num,expr): 将数字按转换单位转换成相应 interval day to second 时间段类型,

                转换单位expr必须是以下值之一:day,hour,minute 或 second。


  numtoyminterval(num,expr): 将数字按转换单位转换成相应 interval year to month 时间段类型,

                转换单位expr必须是以下值之一:day,hour,year 或 month。

select NUMTOYMINTERVAL(100000000, 'MONTH'),
       NUMTOYMINTERVAL(100000, 'YEAR'),
       NUMTODSINTERVAL(150, 'DAY'),
       NUMTODSINTERVAL(1500, 'HOUR'),
       NUMTODSINTERVAL(15000, 'MINUTE'),
       NUMTODSINTERVAL(150000, 'SECOND')
from dual;

运行结果:

NUMTOYMINTERVAL(100000000,'MONTH')                                                   
-------------------------------------------------------------------------------- 
+008333333-04                                                                    

NUMTOYMINTERVAL(100000,'YEAR')                                                   
-------------------------------------------------------------------------------- 
+000100000-00                                                                    

NUMTODSINTERVAL(150,'DAY')                                                       
-------------------------------------------------------------------------------- 
+000000150 00:00:00.000000000                                                    
                                                                                
NUMTODSINTERVAL(1500,'HOUR')                                                      
--------------------------------------------------------------------------------  
+000000062 12:00:00.000000000                                                     
                                                                                  
NUMTODSINTERVAL(15000,'MINUTE')                                                    
-------------------------------------------------------------------------------- 
+000000010 10:00:00.000000000                                                    

NUMTODSINTERVAL(150000,'SECOND')                                                  
--------------------------------------------------------------------------------
+000000001 17:40:00.000000000

       to_dsinterval(s1): 将字符串s1转换为interval day TO second类型的数据
   to_yminterval(s1): 将字符串s1转换为interval year to month类型的数据。

1 select to_dsinterval('150 08:30:00'),
2        to_dsinterval('80 12:30:00'),
3        to_yminterval('03-11'),
4        to_yminterval('01-05')
5  from dual;

运行结果:

 1 TO_DSINTERVAL('15008:30:00')                                         
 2 ---------------------------------------------------------------------
 3 +000000150 08:30:00.000000000                                        
 4 
 5 TO_DSINTERVAL('8012:30:00')                                          
 6 ---------------------------------------------------------------------
 7 +000000080 12:30:00.000000000                                        
 8                                                                      
 9 TO_YMINTERVAL('03-11')                                               
10 ---------------------------------------------------------------------
11 +000000003-11                                                        
12 
13 TO_YMINTERVAL('01-05')                                               
14 ---------------------------------------------------------------------
15 +000000001-05

CHR(number_code):chr函数将ASCII码number_code转换为对应字符:ASCI;  

ASCII(single_character): ascii函数将字符single_character转换为对应ASCII码:字符 -----> ASCII码

chr(9) --制表符
chr(10) --换行符
chr(13) --回车符
chr(32) --空格符
chr(34) --双引号“"”

五、SQL聚合函数(分组函数)

  min( [distinct|all] <列名> | * ): 求一列值中的最小值      
  max( [distinct|all] <列名> ): 求一列值中的最大值      
  sum( [distinct|all] <列名> ): 计算一列值的总和        
  count( [distinct|all] <列名> | * ): 统计一列值的中的个数 ,为*时统计记录的条数
  avg( [distinct|all]< 列名> ): 计算一列值的平均值    

1 select count(distinct ename),count(*),
2        min(sal),
3        max(sal),
4        sum(sal),
5        avg(sal) 
6  from emp;

运行结果:

1 COUNT(DISTINCTENAME)   COUNT(*)   MIN(SAL)   MAX(SAL)   SUM(SAL)   AVG(SAL)
2 -------------------- ---------- ---------- ---------- ---------- ----------
3                   14         14        800    5000.25   29226.58 2087.61285

六、分析函数

  rank(expr1,expr2,...) within group(order by col1,col2,...):返回特定数值在统计数值中的排序值,expr1,expr2,...必须为常数

  rank() over( [query_partition_clause] order_by_clause ) :从一个查询结果中计算每一行的排序值,排序基于order_by_clause子句中的value_exprs指定的字段

1 -- demo:返回1530在所有工资中所占的等级     
2 select rank(1530) within group(order by sal asc) rank_level
3 from emp;
4 RANK_LEVEL
5 ----------
6          8
--demo:返回所有部门的每个员工的工资等级
select rank() over(order by sal asc) as rank_level,ename 
from emp where deptno = 30;

RANK_LEVEL ENAME
---------- ----------
         1 JAMES
         2 WARD
         3 MARTIN
         4 TURNER
         5 ALLEN
         6 BLAKE

      dense_rank(expr1,expr2,...) within group(order by expr1,expr2,...):返回特定数值在一组行数据中的等级

  dense_rank() over( [query_partition_clause] order_by_clause ):从一个查询结果中计算每一行的排序值,排序基于

                                                                                                                    order_by_clause子句中的value_exprs指定的字段

  注:dense_rank与rank()的区别:

   聚合函数RANK 和 dense_rank 主要的功能是计算一组数值中的排序值。

   dense_rank与rank()用法相当,dence_rank在并列关系中相关等级不会跳过,rank则会跳过.rank()是跳跃排序,

   有两个第二名时接下来就是第四名(同样是在各个分组内) dense_rank()是连续排序,有两个第二名时仍然跟着第三名。

1 -- demo:返回1530在所有工资中所占的等级     
2 SQL> select dense_rank(1530) within group(order by sal asc) dense_rank_level
3     from emp;
4 DENSE_RANK_LEVEL
5 ----------------
6                8
--demo:返回所有部门的每个员工的工资等级
SQL> select dense_rank() over(order by sal asc) as rank_level,ename
      from emp where deptno = 20;
RANK_LEVEL ENAME
---------- ----------
         1 SMITH
         2 ADAMS
         3 JONES
         4 FORD
         4 SCOTT

        row_number() over (partition by col1 order by col2) : 表示根据col1分区,在分组内部根据 col2排序,而这个值就表示每组内部排序后的

                                                              顺序编号(组内连续的唯一的) row_number() 返回的主要是“行”的信息,并没有排名.

--demo:根据deptno分组,在分组内部根据 sal排序
SQL> select row_number() over(partition by deptno order by sal) from emp where deptno < 30;
ROW_NUMBER()OVER(PARTITIONBYDE
------------------------------
                             1
                             2
                             3
                             1
                             2
                             3
                             4
                             5

       percent_rank(expr1,expr2,...) within group(order by expr1,expr2,...):返回特定数值的统计数值在统计级别中所占的比例

SQL> select ename,percent_rank() over(order by sal) percent,rank() over(order by sal) ,sal from emp;
ENAME         PERCENT RANK()OVER(ORDERBYSAL)       SAL
---------- ---------- ---------------------- ---------
SMITH               0                      1    800.00
JAMES      0.07692307                      2    950.00
ADAMS      0.15384615                      3   1100.00
WARD       0.23076923                      4   1250.00
MARTIN     0.30769230                      5   1250.25
TURNER     0.38461538                      6   1500.00
MILLER     0.46153846                      7   1500.25
ALLEN      0.53846153                      8   1600.00
CLARK      0.61538461                      9   2450.83
BLAKE      0.69230769                     10   2850.00
JONES      0.76923076                     11   2975.00
SCOTT      0.84615384                     12   3000.00
FORD       0.84615384                     12   3000.00
KING                1                     14   5000.25

       percentile_cont(percent_expr)within group(order by expr):返回在统计级别中处于某个百分点的特定数值(按照连续分布模型确定)
       percentile_disc(percent_expr)within group(order by expr): 返回在统计级别中处于某个百分点的特定数值(按照离散分布模型确定)

1 SQL> select percentile_cont(0.25)within group(order by sal) from emp;
2 PERCENTILE_CONT(0.25)WITHINGRO
3 ------------------------------
4                      1250.0625
1 SQL> select percentile_disc(0.25)within group(order by sal) from emp;
2 PERCENTILE_DISC(0.25)WITHINGRO
3 ------------------------------
4                           1250

        first:取得排序等级的第一级,然后使用分组函数汇总该等级的数据,该函数不能够单独使用,必须与其它分组函数结合使用。
        last:取得排序等级的最后一级,然后使用分组函数汇总该等级的数据,该函数不能够单独使用,必须与其它分组函数结合使用。

1 SQL> SELECT max(sal)keep(dense_rank first order by sal),deptno from emp group by deptno;
2 MAX(SAL)KEEP(DENSE_RANKFIRSTOR DEPTNO
3 ------------------------------ ------
4                        1500.25     10
5                            800     20
6                            950     30
1 SQL> SELECT max(sal)keep(dense_rank last order by sal),deptno from emp group by deptno;
2 MAX(SAL)KEEP(DENSE_RANKLASTORD DEPTNO
3 ------------------------------ ------
4                        5000.25     10
5                           3000     20
6                           2850     30

        over ([partition by col1] order by col2) ) :开窗函数,表示依col1分组,依col2在分组类排序,
                                                                               over函数不能够单独使用,必须和其它的分组/分析函数配合使用,over函数不可用在where子句中。

 1 SQL> select ename 姓名,deptno 部门,sal 薪水,
 2   2        sum(sal) over(partition by deptno order by sal),
 3   3        sum(sal) over(partition by deptno),
 4   4        sum(sal) over(order by sal),
 5   5        sum(sal) over()
 6   6        from emp;
 7 姓名           部门        薪水 SUM(SAL)OVER(PARTITIONBYDEPTNO SUM(SAL)OVER(PARTITIONBYDEPTNO SUM(SAL)OVER(ORDERBYSAL) SUM(SAL)OVER()
 8 ---------- ------ --------- ------------------------------ ------------------------------ ------------------------ --------------
 9 SMITH          20    800.00                            800                          10875                      800       29226.58
10 JAMES          30    950.00                            950                        9400.25                     1750       29226.58
11 ADAMS          20   1100.00                           1900                          10875                     2850       29226.58
12 WARD           30   1250.00                           2200                        9400.25                     4100       29226.58
13 MARTIN         30   1250.25                        3450.25                        9400.25                  5350.25       29226.58
14 TURNER         30   1500.00                        4950.25                        9400.25                  6850.25       29226.58
15 MILLER         10   1500.25                        1500.25                        8951.33                   8350.5       29226.58
16 ALLEN          30   1600.00                        6550.25                        9400.25                   9950.5       29226.58
17 CLARK          10   2450.83                        3951.08                        8951.33                 12401.33       29226.58
18 BLAKE          30   2850.00                        9400.25                        9400.25                 15251.33       29226.58
19 JONES          20   2975.00                           4875                          10875                 18226.33       29226.58
20 FORD           20   3000.00                          10875                          10875                 24226.33       29226.58
21 SCOTT          20   3000.00                          10875                          10875                 24226.33       29226.58
22 KING           10   5000.25                        8951.33                        8951.33                 29226.58       29226.58
23 14 rows selected
 1 SQL> select ename 姓名,deptno 部门,sal 薪水,salary_order 排序 from (
 2   2  select ename,deptno,sal,row_number() over(partition by deptno order by sal desc) salary_order
 3   3  from emp)emp_temp;
 4 姓名        部门    薪水      排序
 5 ---------- ------ --------- ----------
 6 KING           10   5000.25          1
 7 CLARK          10   2450.83          2
 8 MILLER         10   1500.25          3
 9 SCOTT          20   3000.00          1
10 FORD           20   3000.00          2
11 JONES          20   2975.00          3
12 ADAMS          20   1100.00          4
13 SMITH          20    800.00          5
14 BLAKE          30   2850.00          1
15 ALLEN          30   1600.00          2
16 TURNER         30   1500.00          3
17 MARTIN         30   1250.25          4
18 WARD           30   1250.00          5
19 JAMES          30    950.00          6
20 14 rows selected

       ntile(n) over(order by col1 ASC| DESC) : 对一个数据分区中的有序结果集进行划分组,将其分组为各个桶,并为每个组分配一个唯一的组编号

SQL> select ename,sal,ntile(3) over (order by sal nulls last) from emp;
ENAME            SAL NTILE(3)OVER(ORDERBYSALNULLSLA
---------- --------- ------------------------------
SMITH         800.00                              1
JAMES         950.00                              1
ADAMS        1100.00                              1
WARD         1250.00                              1
MARTIN       1250.00                              1
MILLER       1300.00                              2
TURNER       1500.00                              2
ALLEN        1600.00                              2
CLARK        2450.00                              2
BLAKE        2850.00                              2
JONES        2975.00                              3
SCOTT        3000.00                              3
FORD         3000.00                              3
KING         5000.00                              3
SQL> select id,grade,ntile(4) over(order by grade desc) from course;
        ID      GRADE NTILE(4)OVER(ORDERBYGRADEDESC)
---------- ---------- ------------------------------
        95                              1
        90                              1
        85                              1
        80                              2
        75                              2
        70                              2
        65                              3
        60                              3
        55                              4
        50                              4

      group_id():区分分组结果中的重复行
      grouping(expr):用于确定分组结果是否用到了特定的运算式
                            返回值0表示用到了该运算式,返回值1表死未用到该运算式
      grouping_id(expr1[,expr2],,,):用于返回对应于特定行的分组位向量的值

 七、其他特殊函数

  SYS_CONNECT_BY_PATH(col1,str) :  oracle 的递归查询函数,该函数是oracle9i新提出的,这个函数要和:START WITH(非必须) 和 CONNECT BY  PRIOR(必须)联合使用,其中 START WITH 表示开始遍历的的节点,CONNECT BY PRIOR 标识父子关系的对应。该函数的两个参数分别是(形成树的字段名,层级分隔符);

 1 SQL> select empno,ename,mgr,sys_connect_by_path(ename,'-->') path from emp
 2          start with ename = 'KING' connect by prior empno = mgr;
 3 EMPNO ENAME        MGR PATH
 4 ----- ---------- ----- --------------------------------------------------------------------------------
 5 KING             -->KING
 6 JONES       7839 -->KING-->JONES
 7 SCOTT       7566 -->KING-->JONES-->SCOTT
 8 ADAMS       7788 -->KING-->JONES-->SCOTT-->ADAMS
 9 FORD        7566 -->KING-->JONES-->FORD
10 SMITH       7902 -->KING-->JONES-->FORD-->SMITH
11 BLAKE       7839 -->KING-->BLAKE
12 gxl         7698 -->KING-->BLAKE-->gxl
13 ALLEN       7698 -->KING-->BLAKE-->ALLEN
14 WARD        7698 -->KING-->BLAKE-->WARD
15 MARTIN      7698 -->KING-->BLAKE-->MARTIN
16 TURNER      7698 -->KING-->BLAKE-->TURNER
17 JAMES       7698 -->KING-->BLAKE-->JAMES
18 CLARK       7839 -->KING-->CLARK
19 MILLER      7782 -->KING-->CLARK-->MILLER

猜你喜欢

转载自www.cnblogs.com/lgx5/p/12063490.html