1、SQL的函数类型
2、单行函数的函数类型
1.字符函数
lower —— 小写upper —— 大写initcap —— 将字符串首每个单词字母变成大写函数名(表达式)concat —— 字符串拼接concat(str1,str2) ——只支持两个参数如果字符串过多,拼接推荐用 ||select 'hello ' || 'world '|| '1234' || 123 from dual; --123 做了隐式转换substr —— 取子串substr(str , pos , len) --在str里边第pos个字符取子串,长度是len,len可以省略pos 可以是负数,相当于从字符串后边往前面数select substr('hello world',-3 ) from dual; --rldinstr —— 判断某个字符串在另一个字符串的哪个位置instr (str , substr ) --如果找不到,就返回0,找到则返回向相应位置(第几个字符)lpad,rpad —— 左填充,右填充lpad ( str , len , char) -- 往str左边填充char字符到len长度select lpad('hello', 10 , '#') from dual;select lpad('hello', 3 , '#') from dual; --如果字符串长度比len长,就截取trim —— 去除两边空格select trim ( ' Hello world ') from dual;select trim ( 'H' from 'Hello worldH') from dual; --去除两边的Hreplace —— 字符串替换replace(str , substr , replaceString) --从str里边找到substr,替换成 replaceString
A、大小写转换函数
| 函数 | 结果 | 功能 |
|---|---|---|
LOWER('SQL Course') |
sql course | 转全部小写 |
UPPER('SQL Course') |
SQL COURSE | 转全部大写 |
INITCAP('SQL course') |
Sql Course | 首字母大写 |
SELECT employee_id, last_name, department_idFROM employeesWHERE LOWER(last_name) = 'higgins';
B、字符串操作函数
| 函数 | 结果 | 功能 |
|---|---|---|
CONCAT('Hello', 'World') |
HelloWorld | 字符串连接 |
SUBSTR('HelloWorld',1,5) |
Hello | 字符串截取,截取位和截取长度 |
LENGTH('HelloWorld') |
10 | 计算字符串的长度 |
INSTR('HelloWorld', 'W') |
6 | 查找字符在字符串中的位置 |
LPAD(salary,10,'*') |
*24000 | |
RPAD(salary, 10, '*') |
24000* | |
TRIM('H' FROM 'HelloWorld') |
elloWorld | 将某个字符从字符串中删除 |
TRIM(' HelloWorld') |
HelloWorld | 删除字符串中的空白格 |
TRIM('Hello World') |
Hello World |
SELECT employee_id,CONCAT(first_name, last_name) NAME,job_id,LENGTH (last_name),INSTR(last_name, 'a') "Contains 'a'?"FROM employeesWHERE SUBSTR(job_id, 4) = 'REP';
2.数值操作函数
round —— 四舍五入trunc —— 截取ceil、floor —— 向上取整、向下取整mod —— % 取模selectround(45.926) 四舍五入,round(45.926,1) 四舍五入保留一位小数,trunc(45.926) 截取,trunc(45.926,1) 截取并保留一位小数,ceil(45.926) 向上取整,floor(45.926) 向下取整,mod(1000,600) 取模from dual


| 函数 | 结果 | 说明 |
|---|---|---|
ROUND(45.926, 2) |
45.93 | 保留两位小数位进行四舍五入 |
TRUNC(45.926, 2) |
45.92 | 保留两位小数位进行截取 |
MOD(1600, 300) |
100 | 求模取余 |
A、ROUND
SELECTROUND(45.923,2),ROUND(45.923,0),ROUND(45.923,-1)FROM DUAL;
B、TRUNC
SELECT TRUNC(45.923,2), TRUNC(45.923), TRUNC(45.923,-2)FROM DUAL;
C、MOD
SELECT last_name, salary, MOD(salary, 5000)FROM employeesWHERE job_id = 'SA_REP';
3.日期操作函数
sysdate —获取当前系统的时间
sysdate 不仅包含日期,还包含时间
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
1、显示昨天、今天、明天
日期类型的计算 +1 -1 单位是天
select sysdate -1 昨天 , sysdate 今天 , sysdate +1 明天 from dual;
2、计算员工工龄,按照日、周、月、年显示
日期相减,得到两个日期相隔多少天
select ename ,hiredate,sysdate- hiredate "天",(sysdate - hiredate) / 7 "周",(sysdate - hiredate) / 30 "月",(sysdate - hiredate) / 365 "年"from emp
months_between
months_between(date1 , date2 ) —算出两个时间相差多少个月——精确值
select ename ,hiredate,(sysdate - hiredate) / 30 "月",months_between(sysdate,hiredate) "精确月"from emp
add_months
add_months(date, n) 在date上添加n个月
计算明年今日
select add_months(sysdate,12) "明年今日" from dual;
last_day
last_day(date) —返回date 所在 月的最后一天
select last_day(sysdate) from dual;
next_day
next_day(sysdate,'星期三') — 返回下一个星期几是哪一天
select next_day(sysdate,'星期三') from dual;
| 函数 | 结果 |
|---|---|
MONTHS_BETWEEN ('01-SEP-95','11-JAN-94') |
19.6774194 |
ADD_MONTHS ('11-JAN-94',6) |
11-Jul-94 |
NEXT_DAY ('01-SEP-95','FRIDAY') |
8-Sep-95 |
NEXT_DAY ('01-SEP-95',1) |
3-Sep-95 |
NEXT_DAY ('1995-09-01',1) |
ORA01861:literal does not match format string |
NEXT_DAY (to_date('1995-09-01','YYYY-MM-DD'),1) |
3-Sep-95 |
LAST_DAY('01-FEB-95') |
28-Feb-95 |
ROUND('25-JUL-95','MONTH') |
1-Aug-95 |
ROUND('25-JUL-95' ,'YEAR') |
1-Jan-96 |
TRUNC('25-JUL-95' ,'MONTH') |
1-Jul-95 |
TRUNC('25-JUL-95','YEAR') |
1-Jan-95 |
SELECT last_name, (SYSDATE-hire_date)/7 AS WEEKS, sysdate+1 astomorrow , hire_date + 8/24FROM employeesWHERE department_id = 90;
4.类型转换函数

数字转字符串 to_charto_char(数字)to_char(数字,格式字符串)将薪水转化为本地货币字符型select to_char(sal,'L9999') from emp; -L 代表本地货币符号 ,9代表一位数字符串转数字 to_numberselect to_number('1234') from dual;select to_number('¥950','L9999') from dual;用什么格式转到数字类型的,就用什么格式转回去字符串日期转字符串 to_charhiredate 转字符串select hiredate ,to_char(hiredate , 'dd-mm-yyyy day') from emp;字符串转日期 to_dateselect to_date( '17-12-1980 星期三' , 'dd-mm-yyyy day') from dual;
A、隐式转换规则
Oracle 数据类型的隐私转换规则:
对于赋值操作可以:
| 从 | 到 |
|---|---|
| VARCHAR2 or CHAR | NUMBER |
| VARCHAR2 or CHAR | DATE |
| NUMBER | VARCHAR2 |
| DATE | VARCHAR2 |
对于表达式比较操作仅可以:
| 从 | 到 |
|---|---|
| VARCHAR2 or CHAR | NUMBER |
| VARCHAR2 or CHAR | DATE |
B、显式转换规则
TO_CHAR() 函数:日期到字符串的转换
| 日期格式化元素 | 意义 |
|---|---|
| YYYY | 4位数字表示的年份 |
| YEAR | 英文描述的年份 |
| MM | 2位数字表示的月份 |
| MONTH | 英文描述的月份 |
| MON | 三个字母的英文描述月份简称 |
| DD | 2位数字表示的日期 |
| DAY | 英文描述的星期几 |
| DY | 三个字母的英文描述的星期几简称 |
| HH24:MI:SS AM | 时分秒的格式化 |
| DDspth | 英文描述的月中第几天 fm 格式化关键字,可选 |
SELECT last_name, TO_CHAR(hire_date, 'fmDD "of" Month YYYY')AS HIREDATEFROM employees;
TO_CHAR() 函数:数字到字符串的转换
| 数字格式化元素 | 意义 |
|---|---|
| 9 | 表示一个数字 |
| 0 | 强制显示0 |
| $ | 放一个美元占位符 |
| L | 使用浮点本地币种符号 |
| . | 显示一个小数点占位符 |
| , | 显示一个千分位占位符 |
SELECT TO_CHAR(salary, 'L99,999.00') SALARYFROM employeesWHERE last_name = 'Ernst';
TO_NUMBER() 函数:字符串到数字的转换
| TO_NUMBER应用 | 正确与否 |
|---|---|
select TO_NUMBER('4456') from dual; |
√ |
select TO_NUMBER('$4,456') from dual; |
Ⅹ |
select TO_NUMBER('$4,456','$9,999' )from dual; |
√ |
select TO_NUMBER('$4,456,455.000','$9,999.999' )from dual; |
Ⅹ |
select TO_NUMBER('$4,456,455.000','$9,999,999,999,999.999' )from dual; |
√ |
TO_DATE() 函数:字符串到日期的转换
| TO_DATE应用 | 正确与否 |
|---|---|
select to_date ('22-FEB-11') from dual; |
√ |
select to_date('2011-2-22') from dual; |
Ⅹ |
select to_date('2011-2-22','YYYY-MM-DD') from dual; |
√ |
select to_date('2-22-2011','MM-DD-YYYY') from dual; |
√ |
select to_date('2011-FEB-22','YYYY-MON-DD') from dual; |
√ |
TO_DATE() 函数:日期转换时使用RR格式的注意事项
C、函数嵌套
单行函数可以被无限层的嵌套,计算时先计算里层,再计算外层
SELECT last_name, NVL(TO_CHAR(manager_id), 'No Manager')FROM employeesWHERE manager_id IS NULL;
5.其他常用单行函数
nvlnvl(exp,retval) 如果exp是空,就返回retval,否则返回expnvl2nvl2(exp , val1 , val2) 如果exp不为空 ,返回val1, 否则返回val2查询员工信息,有奖金就显示'有奖金',没奖金就显示'没奖金'
| 函数 | 用途 |
|---|---|
NVL (expr1, expr2) |
如果expr1为空,这返回expr2 |
NVL2 (expr1, expr2, expr3) |
如果expr1为空,这返回expr3(第2个结果)否则返回expr2 |
NULLIF (expr1, expr2) |
如果expr1和expr2相等,则返回空 |
COALESCE (expr1, expr2, ..., exprn) |
如果expr1不为空,则返回expr1,结束;否则计算expr2,直到找到 一个不为NULL的值 或者如果全部为NULL,也只能返回NULL 了 |
SELECT last_name, salary, NVL(commission_pct, 0),(salary*12) + (salary*12*NVL(commission_pct, 0)) AN_SALFROM employees;

SELECT last_name, salary, commission_pct,NVL2(commission_pct,'SAL+COMM', 'SAL') incomeFROM employeesWHERE department_idIN (50, 80);

SELECT first_name, LENGTH(first_name) "expr1",last_name, LENGTH(last_name) "expr2",NULLIF(LENGTH(first_name), LENGTH(last_name)) resultFROM employees;

SELECT first_name, LENGTH(first_name) "expr1",last_name, LENGTH(last_name) "expr2",NULLIF(LENGTH(first_name), LENGTH(last_name)) resultFROM employees;

SELECT last_name, COALESCE(commission_pct, salary, 10) commFROM employeesORDER BY commission_pct;
3、条件表达式
条件表达式:
实现方法:
CASE 语句或者DECODE函数,两者均可实现 IF-THEN-ELSE 的逻辑,相比较 而言,DECODE 更加简洁。
CASE 语句
CASE exprWHEN comparison_expr1 THEN return_expr1[WHEN comparison_expr2 THEN return_expr2WHEN comparison_exprn THEN return_exprnELSE else_expr]END
SELECT last_name, job_id, salary,CASE job_idWHEN 'IT_PROG' THEN 1.10*salaryWHEN 'ST_CLERK' THEN 1.15*salaryWHEN 'SA_REP' THEN 1.20*salaryELSE salaryEND "REVISED_SALARY"FROM employees;
DECODE函数
DECODE(col|expression, search1, result1 [, search2, result2,...,][, default])
SELECT last_name, job_id, salary,DECODE(job_id,'IT_PROG', 1.10*salary,'ST_CLERK', 1.15*salary,'SA_REP', 1.20*salary,salary) REVISED_SALARYFROM employees;

