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;--抽取年份的三種方法