1. 程式人生 > >Oracle 單行函式和多行函式(組函式、聚合函式)

Oracle 單行函式和多行函式(組函式、聚合函式)

Oracle中函式主要分為單行函式和多行函式

一、特點:

  1. 單行函式可以多層巢狀,多行函式(組函式)只能巢狀兩層(多層巢狀沒有意義)。
  2. 多行函式通常用於整表或分組統計查詢中
  3. 每次處理完一條記錄返回一個結果

二、常見的單行函式(數量比較多):

  • lower    轉小寫
  • upper    轉大寫
  • initcap   首字母大寫
select lower('hello Mack'),upper('hello Mack'),initcap('hello Mack') from dual;

LOWER('HEL UPPER('HEL INITCAP('H
---------- ---------- ----------
hello mack HELLO MACK Hello Mack
  • substr(a,b)  從a中第b位開始取字元
  • substr(a,b,c) 從a中第b位開始取c個字元
select substr('hello world',3) 子串 from dual;

子串
---------
llo world

select substr('hello world',3,4) 子串 from dual;

子串
----
llo
  • instr(a,b)  在a中查詢b,返回b所在的位置
select instr('hello','l')位置 from dual;

      位置
----------
         3

select instr('hello','a')位置 from dual;

      位置
----------
         0
  • length  返回字元數  
  • lengthb    返回位元組數
select length('hello') 字元數,lengthb('hello') 位元組數 from dual;

    字元數     位元組數
---------- ----------
         5          5

select length('中國,你好!') 字元數,lengthb('中國,你好!') 位元組數 from dual;

    字元數     位元組數
---------- ----------
         6         12
  • lpad 左填充  
  • rpad 右填充
select lpad('abc',10,'*')左,rpad('abc',10,'*') 右 from dual;

左         右
---------- ----------
*******abc abc*******
  • trim 去掉前後指定的字元
select trim('*' from '*hello world!*') trim from dual;

TRIM
------------
hello world!
  • replace  替換字元
select replace('hello world','l','*')替換 from dual;

替換
-----------
he**o wor*d
  • round   四捨五入
select round(11.981,2) 一,round(11.981,1) 二,round(11.981,0) 三,round(11.981,-1) 四,round(11.981,-2) 五  from dual;

        一         二         三         四         五
---------- ---------- ---------- ---------- ----------
     11.98         12         12         10          0
  • trunc 截斷
select trunc(11.981,2) 一,trunc(11.981,1) 二,trunc(11.981,0) 三,trunc(11.981,-1) 四,trunc(11.981,-2) 五  from dual;

        一         二         三         四         五
---------- ---------- ---------- ---------- ----------
     11.98       11.9         11         10          0
  • sysdate     查詢當前時間
select sysdate from dual;

SYSDATE
--------------
26-12月-18
  • to_char(date,格式)   格式轉換
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss')時間  from dual;

時間
-------------------
2018-12-26 11:56:02
  • to_date(date,格式)    格式轉換
select to_date('2015-12-13 12:23:55','yyyy-mm-dd hh24:mi:ss')時間 from dual;

時間
--------------
13-12月-15
  • to_number(date,格式)   格式轉換
select to_number('¥12345','L999999') from dual;

TO_NUMBER('¥12345','L999999')
------------------------------
                         12345
  • sysdate-1:昨天,sysdate:今天,sysdate+1:明天
select (sysdate-1)昨天,sysdate 今天,(sysdate+1) 明天 from dual;

昨天           今天           明天
-------------- -------------- --------------
25-12月-18     26-12月-18     27-12月-18
  • months_between(a,b)     計算兩個日期相差的月數
select ename,hiredate,months_between(sysdate,hiredate) 月 from emp;

ENAME      HIREDATE               月
---------- -------------- ----------
SMITH      17-12月-80     456.309836
ALLEN      20-2月 -81     454.213062
WARD       22-2月 -81     454.148546
JONES      02-4月 -81     452.793707
  • add_months(a,b)  :給日期a加上b個月
select sysdate 現在, add_months(sysdate,12) 一年後 from dual;

現在           一年後
-------------- --------------
26-12月-18     26-12月-19
  • last_day : 某個日期當前月份的最後一天
select sysdate 現在, last_day(sysdate)月末 from dual;

現在           月末
-------------- --------------
26-12月-18     31-12月-18
  • next_day(a,b):a日期後的第一星期b
select sysdate 現在, next_day(sysdate,'星期一')下個星期一 from dual;

現在           下個星期一
-------------- --------------
26-12月-18     31-12月-18
  • round(a,b):四捨五入a日期,精確度為b
select sysdate 現在,round(sysdate,'year') 精確度為年,round(sysdate,'month') 精確度為月 from dual;

現在           精確度為年     精確度為月
-------------- -------------- --------------
26-12月-18     01-1月 -19     01-1月 -19
  • nullif(a,b):    當a=b的時候,返回null;否則返回a 
select nullif('abcd','abc') 值,nullif('ad','ad') 值 from dual;

值   值
---- --
abcd
  • coalesce:   從左到右找到第一個不為null的值 
select comm,sal,coalesce(comm,sal) "第一個非null值" from emp;

      COMM        SAL 第一個非null值
---------- ---------- --------------
                  800            800
       300       1600            300
       500       1250            500
  • nvl(a,b) :   當a=null時返回b
select nvl(comm,0)comm from emp;

      COMM
----------
         0
       300
       500
         0
      1400
  • case表示式  
select ename,job,sal 漲前,case job when 'PRESIDENT' then sal+1000 when 'MANAGER' then sal+800 else sal+400 end 漲後 from emp;

ENAME      JOB             漲前       漲後
---------- --------- ---------- ----------
JONES      MANAGER         2975       3775
MARTIN     SALESMAN        1250       1650
BLAKE      MANAGER         2850       3650
CLARK      MANAGER         2450       3250
KING       PRESIDENT       5000       6000
  • decode 函式(功能和case end相同,但更簡潔)
select ename,job,sal 漲前,decode(job,'PRESIDENT',sal+1000,'MANAGER',sal+800,sal+400)漲後 from emp;

ENAME      JOB             漲前       漲後
---------- --------- ---------- ----------
JONES      MANAGER         2975       3775
MARTIN     SALESMAN        1250       1650
BLAKE      MANAGER         2850       3650
CLARK      MANAGER         2450       3250
KING       PRESIDENT       5000       6000

三、常見的多行函式(還有幾個不常用):

  • max()     返回最大值,忽略空值
  • min()      返回最小值,忽略空值
  • count()    返回記錄數量,若為空用*表示,否則忽略
  • avg()       返回平均值,忽略空值
  • sum()      返回總數,忽略空值

用法比較簡單,如:

select max(sal),min(sal),avg(sal),sum(sal),count(*) from emp;

注意:在查詢語句中,當多行函式和其它列名同時是查詢結果時要使用group by進行分組,否則會出現錯誤:ORA-00937: 非單組分組函式 。