1. 程式人生 > 其它 >Oracle筆記04——Oracle單行函式

Oracle筆記04——Oracle單行函式

SQL函式分為單行函式多行函式


單行函式

(1)字元函式

大小寫轉換函式:

①小寫轉換函式

LOWER({列名 | 變數 | 表示式})

②大寫轉換函式

UPPER({列名 | 變數 | 表示式})

③首字母大寫函式

INITCAP({列名 | 變數 | 表示式})

④dual是一行N列的偽表

(2)字元處理函式

①連線兩個值,等同於 | |

CONCAT(列名1 | 表示式1, 列名2 | 表示式2)

②擷取字串

SUBSTR(列名 | 表示式, n1[, n2])
作用:返回第一個引數中,從第n1位開始,長度為n2的子串
注意
Ⅰ.如果n2被省略,則取第n1到最後的所有字元
Ⅱ.如果n1是負數,表示從第一個引數的後面第(-n1)位開始向右取長度為n2的子串

③取字元長度

LENGTH(列名 | 表示式)

④獲取子串在字串中出現的位置的下標

INSTR(引數1, 引數2 [,引數3,引數4])
其中:
引數1:待查詢的目標字串
引數2:要查詢的子串
引數3:開始查詢的位置,預設從1開始
引數4:要查詢第N次出現的子串

⑤左補齊

LPAD(引數1, 引數2, 引數3)
其中:
引數1:帶補齊的目標字串
引數2:想要得到的字串長度
引數3:不足長度的向左補齊的字串

⑥右補齊

RPAD(引數1, 引數2, 引數3)
其中:
引數1:帶補齊的目標字串
引數2:想要得到的字串長度
引數3:不足長度的向右補齊的字串

⑦去除字串頭部或尾部或頭尾的字元

TRIM( [LEADING | TRAILING | BOTH 字元 FROM] 字串)


其中:
LEADING為頭部,TRAILING為尾部,BOTH為頭部和尾部

⑧替換字串

REPLACE(引數1, 引數2, 引數3)
其中:
引數1:源字串
引數2:源字串中要被替換的字串
引數3:要替換引數2的字串


(3)數值函式

①四捨五入

ROUND(列名 | 表示式 [, n])
注意:
Ⅰ.當有兩個引數的時候,表示結果保留小數點後第n位;
Ⅱ.當只有一個引數的時候,表示結果保留整數
Ⅲ.當n為負數時,表示整數第(-n)位開始四捨五入,大於等於5向前進1;小於5,取0;

②擷取小數點第n位

TRUNC(列名 | 表示式 [, n])
注意:
Ⅰ.當有兩個引數的時候,表示結果擷取到小數點第n位;
Ⅱ.當只有一個引數的時候,表示結果保留整數
Ⅲ.當n為負數時,表示整數第(-n)位到最後一位都取0
③取m除於n得到的餘數
MOD(m,n)


(4)日期函式

①返回系統當前日期

SYSDATE

②RR日期格式:用來判定按照DD-MON-RR格式給定的日期實際代表的日期是多少

大大 不變
大小 世紀+1
小小 不變
小大 世紀-1

③返回兩個日期型別資料之間間隔的自然月份

MONTHS_BETWEEN(日期型別資料1, 日期型別資料2)

④返回指定日期加上相應的月份後的日期

ADD_MONTHS(日期型別資料, 月份)

⑤返回某一日期的下一個指定星期

NEXT_DAY(日期型別資料, 星期幾)

⑥返回某一日期所在月份的最後一天

LAST_DAY(日期型別資料)

⑦四捨五入日期

ROUND(日期型別資料[, 'YEAR' | 'MONTH' | 'DAY'])

⑧截斷日期

TRUNC(日期型別資料[, 'YEAR' | 'MONTH' | 'DAY'])

⑨返回日期型別資料中的年份、月份或者日

EXTRACT([YEAR | MONTH | DAY] FROM 日期型別資料)

(5)轉換函式

TO_CHAR(資料, ['fmt'])

Ⅰ.當資料為日期型資料時,功能為:將日期型別資料轉換為[規定日期格式的]字串
日期模型的元素:

YYYY 完整的年份
YEAR 年份的英文
MM 兩位數字的月份
MONTH 月份的全名
DD 日期
DAY 星期幾
DY 用3個英文字元來表示星期幾
HH 小時(其中12HH表示12小時制,24HH表示24小時制)
MI 分鐘
SS
AM 上午
PM 下午


Ⅱ.當資料為數值型資料時,功能為:將數值型別資料轉換為[規定日期格式的]字串
數值模型的元素:

9 一位數字
0 顯示前導0
$ 顯示美元符號
L 顯示本地貨幣符號
. 顯示小數點
, 顯示千位符


注意:進行數字型別到字元型轉換時,格式中的寬度一定要超過實際列寬度,否則會顯示為###

②將字串轉換為數值

TO_NUMBER(字串)

③將字串轉換為日期

TO_DATE(字串, ['fmt'])
注意:當字串為日期的預設格式的日期型別資料即'日-月-年'時,才可以省略'fmt'


(6)通用函式

①判斷引數一是否為空,如果為null,取引數二的值;反之,取引數一本身的值

NVL(引數一, 引數二)

②判斷引數一是否為空,不為空取引數二的值,為空取引數三的值

NVL2(引數一, 引數二, 引數三)

③判斷引數一與引數二是否相等,相等返回null,不等返回引數一

NULLIF(引數一, 引數二)

④判斷引數一是否為空,不為空取引數一的值;為空則判斷引數二是否為空,引數二不為空取引數二的值,為空判斷引數三是否為空...

COALESCE(引數一, 引數二, 引數三, ..., 引數N)

⑤判斷表示式,如果滿足表示式1,返回值1;如果滿足表示式2,返回值2;...;如果都不滿足返回else值

CASE 表示式
WHEN 表示式1 THEN 值1
WHEN 表示式1 THEN 值2
WHEN 表示式1 THEN 值3
...
WHEN 表示式N THEN 值N
ELSE else值
END

⑥如果表示式的值等於表示式1,返回值1;如果表示式的值等於表示式2,返回值2;如果表示式的表示式等於值3,返回值3;...;都不相等返回預設值

DECODE(表示式, 表示式1, 值1, 表示式2, 值2, 表示式3, 值3, ... , 預設值)

(7)函式巢狀

單行函式可以巢狀N層


(8)抽取日期的三種

①EXTRACT()
②SUBSTR()
③TO_CHAR()

(9)練習

--1.字元函式
--(1)大小寫轉換函式
SELECT ename,LOWER(ename),job FROM emp;--轉小寫
SELECT 'SQL source',LOWER('SQL source') FROM dual;--dual偽表
SELECT 'SQL source',UPPER('SQL source') FROM dual;--轉大寫
SELECT 'sql source',INITCAP('sql source') FROM dual;--首字母大寫
--(2)字元處理函式
SELECT ename,sal FROM emp;
SELECT CONCAT(ename,sal) FROM emp;--拼接兩個列的值
SELECT CONCAT(CONCAT(ename,'的薪水為:'),sal) FROM emp;--函式的巢狀

SELECT '[email protected]',SUBSTR('[email protected]',5) FROM dual;--從下標為5開始擷取到最後
SELECT '[email protected]',SUBSTR('[email protected]',5,2) FROM dual;--從下標為5開始擷取,擷取長度為2的子串
SELECT '[email protected]',SUBSTR('[email protected]',-6,2) FROM dual;--從後面第6位開始擷取,擷取長度為2的子串

SELECT '[email protected]', LENGTH('[email protected]') FROM dual;--獲取字串的長度
SELECT ename,LENGTH(ename) FROM emp;--獲取所有員工姓名的長度

SELECT '[email protected]', INSTR('[email protected]','lqh') FROM dual;--查詢'lqh'第一次出現的位置
SELECT '[email protected]', INSTR('[email protected]','lqh',2) FROM dual;--從2開始查詢'lqh'第一次出現的位置
SELECT '[email protected]', INSTR('[email protected]','q',2,2) FROM dual;--從2開始查詢'q'第二次出現的位置

SELECT ename, '' || LPAD(sal, 10 , '-') AS 薪水 FROM emp;--薪水不足10位的向左補'-'
SELECT ename, RPAD(ename, 10,'_') AS 員工姓名 FROM emp;--員工姓名不足10位的向右補'_'

SELECT ' [email protected] ', TRIM(' [email protected] ') FROM dual;--預設除去首尾空格
SELECT '[email protected]_', TRIM(LEADING '_' FROM '[email protected]_') AS 去除頭部字元 FROM dual;--去除頭部字元'_'
SELECT '[email protected]_', TRIM(TRAILING '_' FROM '[email protected]_') AS 去除尾部字元 FROM dual;--去除尾部字元'_'
SELECT '[email protected]_', TRIM(BOTH '_' FROM '[email protected]_') AS 去除頭尾字元 FROM dual;--去除頭尾字元'_'

SELECT '[email protected]',REPLACE('[email protected]', 'qq', 'wechat') AS 替換後的字串  FROM dual;--將字串中的'qq'替換成'wechat'
SELECT '[email protected]',REPLACE('[email protected]', 'q', '*') AS 替換後的字串  FROM dual;--將字串中所有'q'替換成'*'

--(3)數值函式
SELECT ROUND(520.131396), ROUND(520.131396, 4) FROM dual;--取整, 保留小數點後四位小數
SELECT ROUND(519.131396, -1), ROUND(520.131396, -2) FROM dual;--整數第一位四捨五入,整數第二位四捨五入

SELECT TRUNC(520.131396), TRUNC(520.131396, 4) FROM dual;--擷取整數部分,擷取到小數點第四位
SELECT TRUNC(519.131396, -1), TRUNC(520.131396, -2) FROM dual;--將整數第一位以及之後的數變為0,將整數第二位以及之後的數變為0

SELECT MOD(520,3) FROM dual;--取520/3的餘數

--(4)日期函式
SELECT SYSDATE FROM dual;--獲取系統當前時間

--查詢員工的入職日期,轉正日期(6個月試用期),入職天數,入職星期數等
SELECT hiredate 入職日期,
       hiredate + (6 * 30) 轉正日期,
       (SYSDATE - hiredate) 入職天數,
       (SYSDATE - hiredate) / 7 入職星期數
  FROM emp;

-------------------
當前年份        指定的日期         RR格式
1995            27-12月-95         1995
1995            27-12月-17         2017
2001            27-12月-17         2017
2001            27-12月-95         1995             
-------------------

SELECT MONTHS_BETWEEN('1-12月-12', '1-5月-12') FROM dual;--返回兩個日期相差的月份

SELECT ADD_MONTHS('1-12月-12', 2) FROM dual;--加上兩個月

SELECT NEXT_DAY(SYSDATE, '星期一') FROM dual;--返回系統時間的下一個星期一

SELECT SYSDATE, ROUND(SYSDATE) FROM dual;

SELECT SYSDATE,
       ROUND(SYSDATE, 'YEAR'),      --根據月份進位,1-6不變,7-12進1
       ROUND(SYSDATE, 'MONTH'),     --根據天數進位,1-15不變,16-30進1
       ROUND(SYSDATE, 'DAY')        --根據星期進位,星期日-三不變,星期四-六進1
  FROM dual;

SELECT SYSDATE,
       TRUNC(SYSDATE, 'YEAR'),      --擷取年份,月和日都為1
       TRUNC(SYSDATE, 'MONTH'),     --擷取月份,日為1
       TRUNC(SYSDATE, 'DAY')        --擷取日
  FROM dual;

SELECT SYSDATE,
       EXTRACT(YEAR FROM SYSDATE),      --抽取年
       EXTRACT(MONTH FROM SYSDATE),     --抽取月
       EXTRACT(DAY FROM SYSDATE)        --抽取日
  FROM dual;

--(5)轉換函式
SELECT SYSDATE, TO_CHAR(SYSDATE) FROM dual;--將當前系統時間轉換為字串
SELECT SYSDATE,
       TO_CHAR(SYSDATE, 'YYYY') YYYY,--四位的年分
       TO_CHAR(SYSDATE, 'YEAR') "YEAR",--英文年份
       TO_CHAR(SYSDATE, 'MM') MM,--兩位的月份
       TO_CHAR(SYSDATE, 'MONTH') "MONTH",--全名的月份
       TO_CHAR(SYSDATE, 'DD') DY,--日期
       TO_CHAR(SYSDATE, 'DAY') "DAY",--星期
       TO_CHAR(SYSDATE, 'HH') HH,--小時
       TO_CHAR(SYSDATE, 'MI') MI,--分鐘
       TO_CHAR(SYSDATE, 'SS') "SS",--
       TO_CHAR(SYSDATE, 'YYYY-MM-DD PM HH:MI:SS')--轉換為規定的日期格式的字串
  FROM dual;

SELECT TO_CHAR(5201314, 'L0999,999,999.999') FROM dual;--位數不夠,補零
SELECT TO_CHAR(5201314, 'L999.999') FROM dual;--位數超過了,顯示##################

SELECT TO_NUMBER('520.1313')+0.0001 FROM dual;--將字串轉為數值

SELECT TO_DATE('1-12月-01') FROM dual;--將字串轉為日期
SELECT TO_DATE('2005-12-01') FROM dual;--報錯
SELECT TO_DATE('2005-12-01', 'YYYY-MM-DD') FROM dual;--正確

--(6)通用函式
SELECT comm, NVL(comm, 0), deptno, NVL(deptno, 0) FROM emp;--如果comm和deptno為空

SELECT comm, NVL2(comm ,'不為空', '') FROM emp;--如果comm為空輸出“空”,不為空輸出“不為空”

SELECT NULLIF(520,1314) FROM dual;--如果兩個數相等,返回null,否則返回第一個數

SELECT comm, COALESCE(TO_CHAR(comm), null, null, 'comm為空') FROM emp;--如果comm為空,返回函式引數中不為空的值;不為空,則返回其自身的值

SELECT deptno,
       (CASE deptno
         WHEN 10 THEN
          '銷售部'
         WHEN 20 THEN
          '員工部'
         WHEN 30 THEN
          '經理部'
         ELSE
          '打雜部'
       END)
  FROM emp; --如果部門為10,返回“銷售部”;如果部門為20,返回“員工部”;如果部門為30,返回“經理部”;否則返回“打雜部”

--效果跟上面一樣
SELECT deptno,
       (CASE
         WHEN deptno = 10 THEN
          '銷售部'
         WHEN deptno = 20 THEN
          '員工部'
         WHEN deptno = 30 THEN
          '經理部'
         ELSE
          '打雜部'
       END)
  FROM emp;

--效果跟上面一樣
SELECT deptno, DECODE(deptno, 10, '銷售部', 20, '員工部', 30, '經理部', '打雜部') FROM emp;

--(7)函式巢狀
SELECT mgr, NVL(mgr, '為空') FROM emp;--錯誤,NVL中僅允許存放同類型資料
SELECT mgr, NVL(TO_CHAR(mgr), '為空') FROM emp;--正確,NVL函式裡面巢狀TO_CHAR函式

--抽取日期
SELECT SYSDATE, EXTRACT(YEAR FROM SYSDATE), SUBSTR(SYSDATE,-2), TO_CHAR(SYSDATE, 'YYYY') FROM dual;--抽取年份的三種方法