Oracle之单行函数(字符串函数/数字函数/转换函数/日期函数/通用函数)
虚拟表DUAL介绍:
dual是一张虚拟表,只有一行一列,用来构成select的语法规则。
Oracle的查询中,必须使用“select 列… from 表”的完整语法,当查询单行函数的时候,from后面使用DUAL表,dual表在系统中只有一行一列,该表在输出单行函数时为了select…from的语法完整性而使用。
单行函数:
定义:对于每一个函数应用在表的记录中时,只能输入一行结果,返回一个结果。
常用的单行函数有:
字符串函数:对字符串操作;
数值函数:对数字进行计算,返回一个数字;
转换函数:可以将一种数据类型转换成另外一种数据类型;
日期函数:对日期和时间进行处理。
数值函数:
--ABS(X):求数值X的绝对值
SELECT ABS(124),ABS(-34)
FROM DUAL;
--POWER(X,Y):求X的Y次幂
SELECT POWER(2,3),POWER(2,-1)
FROM DUAL;
--MOD(X,Y):求X除以Y的余数,即取模运算
SELECT MOD(5,2),MOD(5,0)
FROM DUAL;
--ROUND(X[,Y]):
--默认 Y = 0 时,返回数值 X 保留整数的四舍五入的值。
--当 Y 为正整数时,就是四舍五入到小数位第 Y 位的值。
--当 Y 为负整数时,就是四舍五入到小数位左边第 |Y| 位的值。
SELECT ROUND(123.567),ROUND(123.44567,1),ROUND(125.456,-1)
FROM DUAL;
--TRUNC(X[,Y]):返回数值 X 在第 Y 位截断的值。直接截取,不四舍五入。
--默认 Y = 0 时,返回数值 X 截断整数的值。
--当 Y 为正整数时,就是截断到小数位第 Y 位的值。
--当 Y 为负整数时,就是截断到小数位左边第 |Y| 位的值。
SELECT TRUNC(123.567),TRUNC(123.44567,1),TRUNC(125.456,-1)
FROM DUAL;
转换函数:
--TO_CHAR(D[,FMT]):把日期或数字转换成指定格式的字符串。FMT 是格式化字符串。
SELECT TO_CHAR(12345),TO_CHAR(SYSDATE,'yyyy-mm-dd')
FROM DUAL;
--TO_NUMBER(X[,FMT]):把一个字符串以 FMT 格式转换成数字。
SELECT TO_NUMBER('2653') - 53
FROM DUAL;
--TO_DATE(X[,FMT]):把一个字符串以 FMT 格式转换成日期类型。
SELECT TO_DATE('20190831 173309','yyyy-mm-dd hh24:mi:ss')
FROM DUAL;
字符串函数:
--ASCII(X):返回字符 X 的 ASCII 码值。
SELECT ASCII('a'),ASCII('A')
FROM DUAL;
--CONCAT(X,Y):连接字符串 X 和 Y(字符串的拼接)
SELECT CONCAT('hello',' world')
FROM DUAL;
--INSTR(X,STR[,START][,N]):在字符串 X 中查找 STR,可以指定从 START 开始,第 N 次出现的位置。
SELECT INSTR('abcdabcdabcd','bc',2,2),INSTR('abcdabcdabcd','c',3,3)
FROM DUAL;
--LENGTH(X):返回字符串 X 的长度。
SELECT LENGTH('abcdabcdabcd') FROM DUAL;
SELECT ENAME,LENGTH(ENAME) FROM EMP;
--LOWER(X):将字符串 X 全部转换成对应的小写。
--UPPER(X):将字符串 X 全部转换成对应的大写。
SELECT LOWER('hEllO'),UPPER('hEllO')
FROM DUAL;
--INITCAP(X):将字符串 X 中的首写字母转换成对应的大写,其它字符全部变成小写.
--字符串用逗号或者空格隔开,隔开的字符会被当做一个新的字符,首字母大写
SELECT INITCAP('hEllO'),INITCAP('hEllO,wOrL D')
FROM DUAL;
--LTRIM(X[,TRIM_STR]):将字符串 X 左边的连续字符 TRIM_STR 去掉。(默认是去掉空格键)
--RTRIM(X,[TRIM_STR]):将字符串 X 右边的连续字符 TRIM_STR 去掉。(默认是去掉空格键)
--TRIM([TRIM_STR FROM] X):将字符串 X 两边连续的字符 TRIM_STR 去掉。(默认是去掉空格键)
SELECT LTRIM('****abc def ****','*'),RTRIM('****abc def ****','*'),TRIM('*' FROM ' ****abc def ****')
FROM DUAL;
--REPLACE(X,OLD_STR,NEW_STR):将字符串 X 的 OLD_STR 字符全换替换成 NEW_STR字符。
SELECT REPLACE('****abc def ****','*','+')
FROM DUAL;
--SUBSTR(X,START[,LENGTH]):截取字符串 X,从 START 位置开始,截取 LENGTH 个长度的字符。(默认是截取到末尾)
SELECT SUBSTR('****abc def ****',5),SUBSTR('****abc def ****',2,6),SUBSTR('****abc def ***g',-2)
FROM DUAL;
日期函数:
参考:https://blog.csdn.net/qq_33459369/article/details/80305175
--系统日期
SELECT SYSDATE
FROM DUAL;
--ADD_MONTHS(D,N):在日期 D 上增加 N 个月,返回计算后的新日期。
SELECT ADD_MONTHS(SYSDATE,2),
ADD_MONTHS(SYSDATE,-2)
FROM DUAL;
--LAST_DAY(D):返回指定日期 D 当月的最后一天。
SELECT LAST_DAY(SYSDATE),
LAST_DAY(TO_DATE('20200810','yyyymmdd'))
FROM DUAL;
--MONTHS_BETWEEN(DATE1,DATE2):用于计算DATE1和DATE2之间有几个月
--如果DATE1在日历中比DATE2晚,那么MONTHS_BETWEEN()就返回一个正数。
--如果DATE1在日历中比DATE2早,那么MONTHS_BETWEEN()就返回一个负数。
--如果DATE1和DATE2日期一样,那么MONTHS_BETWEEN()就返回一个0。
SELECT MONTHS_BETWEEN(TO_DATE('20200721', 'yyyy-mm-dd'),
TO_DATE('20180305', 'yyyy-mm-dd')) 相隔月数
FROM DUAL;
--ROUND(D[,FMT]):返回一个以 FMT 格式的四舍五入的日期值,D 是日期,FMT 是格式模型。
/*
① 如果 FMT 为“YEAR”,则舍入到某年的 1 月 1 日,即前半年舍去,后半年作为下一年。
② 如果 FMT 为“MONTH”,则舍入到某月的 1 日,即前半月舍去,后半月作为下一月。
③ 默认为“DD”,即月中的某一天,舍入最靠近的那天凌晨,前半天舍去,后半天作为第二天。
④ 如果 FMT 为“DAY”,则舍入到最近的周的周日,即上半周舍去,下半周作为下一周周日。
*/
SELECT SYSDATE,
ROUND(SYSDATE,'year') YEAR_1,
ROUND(SYSDATE - 120,'year') YEAR_2,
ROUND(SYSDATE,'month') MONTH_1,
ROUND(SYSDATE + 2,'month') MONTH_2,
ROUND(SYSDATE,'dd') DD_1,
ROUND(TO_DATE('20200915 110000','yyyymmdd hh24:mi:ss'),'dd') DD_2,
ROUND(SYSDATE,'day') DAY_1,
ROUND(SYSDATE + 2,'day') DAY_2
FROM DUAL;
--TRUNC(D[,FMT]):将日期 D 截取到 FMT 指定的形式,与ROUND类似,但是不对日期进行四舍五入。
/*
① 如果 FMT 为“YEAR”,则截取到某年的 1 月 1 日。
② 如果 FMT 为“MONTH”,则截取到某月的 1 日。
③ 默认为“DD”,即月中的某一天,截取到当天凌晨。
④ 如果 FMT 为“DAY”,则截取到上周的周日。
*/
SELECT SYSDATE,
TRUNC(SYSDATE,'year') YEAR_1,
TRUNC(SYSDATE - 120,'year') YEAR_2,
TRUNC(SYSDATE,'month') MONTH_1,
TRUNC(SYSDATE + 2,'month') MONTH_2,
TRUNC(SYSDATE,'dd') DD_1,
TRUNC(TO_DATE('20200915 110000','yyyymmdd hh24:mi:ss'),'dd') DD_2,
TRUNC(SYSDATE,'day') DAY_1,
TRUNC(SYSDATE + 2,'day') DAY_2
FROM DUAL;
通用函数:
通用函数即是常用的函数
--1.NVL(列,默认值):如果列的值为NULL,则使用默认值表示。
SELECT E.MGR,
NVL(E.MGR,9999),
E.COMM,
NVL(E.COMM,8888)
FROM EMP E;
--2.NVL2(列,返回值1,返回值2):如果列的值不为NULL,则使用返回值1;如果列的值为NULL,则使用返回值2.
SELECT E.COMM,
NVL2(E.COMM,10000,20000)
FROM EMP E;
--3.CASE WHEN 条件1 THEN 返回值1 [WHEN 条件2 THEN 返回值2...] ELSE 默认值 END:
--用于实现多条件判断,如果都不满足则使用默认值。
SELECT E.DEPTNO,
CASE
WHEN E.DEPTNO = 10 THEN
'10部门员工'
WHEN E.DEPTNO = 20 THEN
'20部门员工'
WHEN E.DEPTNO = 30 THEN
'30部门员工'
ELSE
'其他部门员工'
END 部门注释
FROM EMP E;
--将EMP表中的SAL字段进行标注:薪资在800~1500之间标记为'等级A',1501~3000标记为'等级B',
--3001~4500标记为'等级C',其它范围标记为'等级D'。
--方法一
SELECT E.SAL,
CASE
WHEN E.SAL >= 800 AND E.SAL <= 1500 THEN
'等级A'
WHEN E.SAL >= 1501 AND E.SAL <= 3000 THEN
'等级B'
WHEN E.SAL >= 3001 AND E.SAL <= 4500 THEN
'等级C'
ELSE
'等级D'
END 薪资等级
FROM EMP E;
--方法二
SELECT E.SAL,
CASE
WHEN E.SAL BETWEEN 800 AND 1500 THEN
'等级A'
WHEN E.SAL BETWEEN 1501 AND 3000 THEN
'等级B'
WHEN E.SAL BETWEEN 3001 AND 4500 THEN
'等级C'
ELSE
'等级D'
END 薪资等级
FROM EMP E;
--DECODE(列 | 值,判断值1,返回值1,判断值2,返回值2...,默认值):
--用于多值判断,如果列的值与判断值相同,则使用对应的返回值,如果没有满足条件,则显示默认值。
SELECT E.DEPTNO,
DECODE(E.DEPTNO,10,'10部门员工',20,'20部门员工',30,'30部门员工','其它部门员工')
FROM EMP E;
--将EMP表中JOB字段标注:
--'CLERK':'行员','SALESMAN':'销售员','MANAGER':'经理','ANALYST':'分析师',否则都标记为'其它岗位'
--方法一
SELECT E.JOB,
DECODE(E.JOB,'CLERK','行员','SALESMAN','销售员','MANAGER','经理','ANALYST','分析师','其它岗位') 岗位注释
FROM EMP E;
--方法二
SELECT E.JOB,
CASE
WHEN E.JOB = 'CLERK' THEN
'行员'
WHEN E.JOB = 'SALESMAN' THEN
'销售员'
WHEN E.JOB = 'MANAGER' THEN
'经理'
WHEN E.JOB = 'ANALYST' THEN
'分析师'
ELSE
'其它岗位'
END
FROM EMP E;
--EXISTS(子查询):用于判断子查询是否有数据返回,如果有则成立,否则不成立。
SELECT D.*
FROM DEPT D
WHERE EXISTS(SELECT 1 FROM EMP E WHERE E.DEPTNO = D.DEPTNO);
--NOT EXISTS:
SELECT D.*
FROM DEPT D
WHERE NOT EXISTS(SELECT 1 FROM EMP E WHERE E.DEPTNO = D.DEPTNO);