oracle 单行函数学习、习题和答案

单行函数


–单行函数特征
– 单行函数对单行操作
– 每行返回一个结果
– 有可能返回值与原参数数据类型不一致
– 单行函数可以写在SELECT、WHERE、ORDER BY子句中
– 有些函数没有参数,有些函数包括一个或多个参数
– 函数可以嵌套


字符函数(11种): lower upper initcap length concat instr substr lpad rpad trim replace
数值函数: round trunc mod
日期函数: sysdate months_between add_months extract(month from sysdate) round(sysdate[,fmt]) trunc(sysdate[,fmt])
类型转换: to_char to_date to_number
通用函数: nvl nvl2 nullif case decode


–字符函数
–大小写转换函数
–LOWER(列名|表达式):将大写或大小写混合的字符转换成小写
–UPPER(列名|表达式) :将小写或大小写混合的字符转换成大写
–INITCAP(列名表达式) :将每个单词的第一个字母转换成大写,
–其余的字母都转换成小写


–lower() 将所有字母转小写
select lower(ename),lower(job) from emp; – 使用在select语句中,将列名转小写
select ename,lower(ename) 转小写后名称,job,lower(job) 转小写后的职位 from emp where lower(ename) like ‘%s%’;–使用在where语句中

select lower(‘SQL Course’) from dual;–sql course dual伪表,仅存在一行一列

–upper() 将所有字母转大写
select upper(‘SQL Course’) from dual;–SQL COURSE

–initcap() 首字母转大写
select initcap(‘sql course’) from dual;–Sql Course


–字符处理函数
– CONCAT(column1|expression1,column2|expression2)
• 连接两个值 ,等同于||
select ename || ‘的职位是’ || job from emp; –SMITH的职位是CLERK

select concat(ename,’的职位是’,job) from emp;–错误,只能带两个参数
select concat(concat(ename,’的职位是’),job) from emp;–concat函数嵌套使用
–substr(参数一,参数二,[参数三]) 截取字符串
–参数一: 待截取的字符对象
–参数二:截取的开始位置
–参数三:截取的长度
select substr(‘SQL Course’,5) from dual;–Course 包括开始位置,从开始位置截取
select substr(‘SQL Course’,3,4) from dual; –L Co
select substr(‘SQL Course’,-2) from dual; –se
–length(参数一) :获取字符串的长度
select ‘SQL Course’,length(‘SQL Course’) from dual;–10
select ename,length(ename) from emp;

–instr(参数一,参数二,[参数三],[参数四]) 获取指定字符的索引
–参数一:待获取索引位置的字符
–参数二:需获取索引位置的字符
–参数三:开始查找的位置
–参数四:指定字符第N次出现的位置
select instr(‘sql course’,’q’) from dual; –2

select instr(‘sql course’,’s’,3) from dual;–9 从索引位置为3的地方开始搜索字符’s’

select instr(‘sql courses’,’s’,3,2) from dual;–11 从索引位置为3的地方开始搜索字符’s’,查找第2次出现的位置

–lpad(参数一,参数二,参数三) 左补全
select ‘V’ || lpad(empno,10,0) from emp;– V0000007369
select concat(‘V’,lpad(empno,10,0)) from emp; –V0000007369

–rpad()(参数一,参数二,参数三) 右补全
select job,length(job),rpad(job,10,’‘) from emp;–CLERK****

–trim() 去首尾字符
select trim(’ sql course ‘) from dual;–默认去前后空格
select trim(leading ‘I’ from ‘Isql courseI’) from dual; –sql courseI 去除头部的‘I’字符
select trim(trailing ‘I’ from ‘Isql courseI’) from dual; –Isql course 去除尾部的‘I’字符
select trim(both ‘I’ from ‘Isql courseI’) from dual; –sql course 去除首尾部的‘I’字符

–replace() 替换字符串 将参数二的字符替换为参数三的新字符
select replace(’ Sql Cource ‘,’ ‘,”) from dual; –SqlCource
select replace(‘sql Cource’,’s’,’S’) from dual; –Sql Cource

练习
1.写一个查询,用首字母大写,其它字母小写显示雇员的 ename,显
示名字的长度,并给每列一个适当的标签,条件是满足所有雇员名字
的开始字母是J、A 或 M 的雇员,并对查询结果按雇员的ename升序
排序。(提示:使用initcap、length、substr)
select trim(both ‘i’ from ‘i sql course’) from dual;
select trim(leading ‘i’ from ‘i sql coursei’) from dual;
select trim(trailing ‘i’ from ‘i sql coursei’) from dual;

select initcap(ename) “姓名”,length(ename) “长度”
from emp
where substr(ename,1,1) in (‘J’,’A’,’M’)
order by ename asc;

1.查询员工姓名中中包含大写或小写字母A的员工姓名。
select ename from emp where instr(ename,’A’)>0 or instr(ename,’a’)>0;

2.查询部门编号为10或20,入职日期在81年5月1日之后,并且姓名中
包含大写字母A的员工姓名,员工姓名长度(提示,要求使用INSTR函
数,不能使用like进行判断)
select ename,length(ename) from emp where deptno in (10,20) and hiredate>’01-5月-81’
and instr(ename,’A’)>0;

3.查询每个职工的编号,姓名,工资
一一 要求将查询到的数据按照 定的格式合并成一个字符串.
前10位:编号,不足部分用*填充,左对齐
中间10位:姓名,不足部分用*填充,左对齐
充 – 后10位:工资,不足部分用*填充,右对齐
select lpad(empno,10,’‘)||lpad(ename,10,’‘)||rpad(sal,10,’*’) from emp;


–数值函数
–ROUND:将列或表达式所表示的数值四舍五入到小数点后的第n位。
–格式: ROUND(column| expression, n)
–ROUND(45.926, 2) -> 45.93
–TRUNC:将列或表达式所表示的数值截取到小数点后的第n位。
–格式:TRUNC(column| expression, n)
–TRUNC(45.926, 2) -> 45.92
–MOD:取m除以n后得到的余数
–格式:MOD(m,n)
–MOD(1600, 300) ->100


–ROUND:将列或表达式所表示的数值四舍五入到小数点后的第n位。
–格式: ROUND(column| expression, n)
–round() 四舍五入
select round(45.926),round(45.926,2) from dual; –46 45.93
select round(45.926,-1),round(455.926,-2) from dual; –50 500
select round(44.926,-1),round(445.926,-2) from dual; –40 400

–TRUNC:将列或表达式所表示的数值截取到小数点后的第n位。
–格式:TRUNC(column| expression, n)
select trunc(45.926),trunc(45.926,2) from dual; –45 45.92
select trunc(45.926,-1),trunc(455.926,-2) from dual; –40 400
select trunc(44.926,-1),trunc(445.926,-2) from dual; –40 400

–MOD:取m除以n后得到的余数
–格式:MOD(m,n)
select mod(10,3) from dual;–1

练习
1.写一个查询,分别计算100.456 四舍五入到小
数点后第2位,第1位,整数位的值。
select round(100.456,2),round(100.456,1),round(100.456,0) from dual;

2.写一个查询,分别计算100.456 从小数点后第
2位,第1位,整数位截断的值。
select trunc(100.456,2),trunc(100.456,1),trunc(100.456,0) from dual;


–日期函数

–日期处理
–默认的日期形式是: DD-MON-RR
–日期类型可以加减数字,功能是在该日期上加减对应的天
–’0-G-’’5-G-’ 数。如: 10 AUG 06 +15结果是 25 AUG 06
–– 日期类型之间可以进行减操作,功能是计算两个日期之间
–0 G ’ 4 G 间隔了多少天。如:’10-AUG-06’-‘4-AUG-06’结果四
–舍五入后是6天
–如果需要对一个日期进行加减相应小时操作,可以使用
–n/24来实现
–SYSDATE:返回系统当前日期


select ename,(SYSDATE-hiredate)/7 weeks
from emp
where deptno=10;

• 1.查询每个员工截止到现在一共入职多少天?
select ename,round(TO_DATE(‘01-1月-00’)-hiredate) days from emp;

• D-N-1- 2.当前日期为2015年,指定日期格式为DD MON RR,指定日期为01-1
月-01,该日期实际所代表的日期为?
2001
• 3.当前日期为2015年,指定日期格式为DD-MON-RR,指定日期为01-1月-95,
该日期实际所代表的日期为?
1995
• 4.当前日期为1998年,指定日期格式为DD-MON-RR,指定日期为01-1
月-01,该日期实际所代表的日期为?
2001
• 5.当前日期为1998年,指定日期格式为DD-MON-RR,指定日期为01-1
月-95,该日期实际所代表的日期为?
1995
• 6.当前日期为2015年,指定日期格式为DD-MON-YY,指定日期为01-1
月-01,该日期实际所代表的日期为?
2001
• 7.当前日期为1998年,指定日期格式为DD-MON-YY,指定日期为01-1
月-95,该日期实际所代表的日期为?
1995


常用日期函数
– SYSDATE:返回系统日期
– MONTHS_BETWEEN:返回两个日期类型数据之间间隔的自然月数
– D ADD_MONTHS:返回指定日期加上相应的月数后的日期
– NEXT_DAY:返回某一日期的下一个指定日期
– LAST_DAY:返回指定日期当月最后一天的日期
– ROUND(date[,‘fmt’])将date按照fmt指定的格式进行四舍五入,
fmt为可选项,如果没有指定fmt,则默认为DD,将date四舍五入为最
近的天。
格式码:世纪CC,年YY,月MM,日DD,小时HH24,分MI,秒SS
– TRUNC( date[,‘fmt’] )将date按照fmt指定的格式进行截断,fmt为
可选项,如果没有指定fmt,则默认为‘DD’,将date截取为最近的
天。
– EXTRACT:返回日期类型数据中的年份 月份或者日
V1.0
EXTRACT:返回日期类型数据中的年份、月份或者日


–MONTHS_BETWEEN:返回两个日期类型数据之间间隔的自然月数
–大的日期放在前面
SELECT ename, sal,MONTHS_BETWEEN(SYSDATE,hiredate) months
FROM emp
ORDER BY months;

–ADD_MONTHS:返回指定日期加上相应的月数后的日期
SELECT ename, sal, hiredate, ADD_MONTHS(hiredate,3)
FROM emp
WHERE hiredate>’01-1月 -82’;
– NEXT_DAY:返回某一日期的下一个指定日期
–NEXT_DAY 函数演示——返回在02-2月-06之后的下一个周 是什么日期。
SELECT NEXT_DAY(‘02-2月-06’,’星期一(或者是其他的星期几’) NEXT_DAY
FROM DUAL;

–LAST_DAY:返回指定日期当月最后一天的日期
SELECT LAST_DAY(‘02-2月-06’) “LAST DAY”
FROM DUAL;
–ROUND函数演示——查询81年入职的员工姓名,入职日
–期按月四舍五入的日期。
select ename,
hiredate,
round(hiredate),
round(hiredate, ‘year’), –年份按1-6月和7-12月四舍五入到最近的 几几年1月1日
round(hiredate, ‘month’),–月份按1-15日和16-30日四舍五入到最近的 几月1日
round(hiredate, ‘day’) –天数按周一-周三和周四到周日四舍五入到最近的 周日
from emp
where substr(hiredate, -2, 2) = ‘81’; –1980/12/17 17-12月-80

–TRUNC 函数演示——查询81年入职的员工姓名,入职日
–期按月截断的日期。
SELECT empno, hiredate, TRUNC(hiredate, ‘MONTH’)
FROM emp
WHERE SUBSTR(hiredate,-2,2)=’81’;
–- EXTRACT:返回日期类型数据中的年份、月份或者日。
EXTRACT ([YEAR] [MONTH][DAY]
FROM [日期类型表达式])
select extract(year from sysdate) 年,
extract(month from sysdate) 月,
extract(day from sysdate) 日
from dual;
–部门编号是10的部门中所有员工入职月份。
SELECT ename, hiredate,
EXTRACT (MONTH FROM HIREDATE) MONTH
FROM emp
WHERE deptno= 10;


– MONTHS_BETWEEN 函数演示 — — 查询所有员工服务的月数
SELECT ename,MONTHS_BETWEEN(SYSDATE,hiredate) months FROM emp ORDER BY months;

ADD_MONTHS 函数演示 — — 查询 82 年后入职的员工转正日期,
按照3个月试用期考虑
SELECT ename,sal,hiredate,ADD_MONTHS(hiredate,3) new_dat
FROM emp
WHERE hiredate>’01-1月-82’;

—— 返回在 02-2月-06 之后的下一个周
一是什么日期。
SELECT NEXT_DAY(‘02-2月-06’,’星期一’) FROM DUAL;

LAST_DAY 函数演示——返回06年2月2日所在月份的最后一
天。
SELECT LAST_DAY(‘02-2月-06’) FROM DUAL;

ROUND 函数演示 — — 查询 81 年入职的员工姓名 ,入职日
期按月四舍五入的日期。
–注:天数的截断按最近的星期日进行天数加减
SELECT ename,hiredate,ROUND(hiredate,’YEAR’),ROUND(hiredate,’MONTH’),ROUND(hiredate,’DAY’)
FROM emp
WHERE SUBSTR(hiredate,-2,2)=’81’;–DD-MM-RR

– TRUNC 函数演示 — — 查询 81 年入职的员工姓名 , 入职日
期按月截断的日期
SELECT ename,hiredate,TRUNC(hiredate,’MONTH’)
FROM emp
WHERE SUBSTR(hiredate,-2,2)=’81’;

部门编号是10的部门中所有员工入职月份。
SELECT hiredate,EXTRACT(MONTH FROM hiredate) FROM emp WHERE deptno=10;

练习
• 1.查询服务器当前时间
SELECT SYSDATE FROM DUAL;
• 2.查询部门10,20的员工截止到2000年1月1日,工作了多
少个月,入职的月份。(提示:使用
months_between,extract)
SELECT ename,hiredate,ROUND(MONTHS_BETWEEN(‘01-1月-00’,hiredate)) mon,
EXTRACT(MONTH FROM hiredate) hire_month FROM emp
WHERE deptno in (10,20);

• 3.如果员工试用期6个月,查询职位不是MANAGER的员工姓
名,入职日期,转正日期,入职日期后的第一个星期一,
入职当月的最后一天日期。(提示:使用
add_months,next_day,last_day)
SELECT ename,hiredate,ADD_MONTHS(hiredate,6),
NEXT_DAY(hiredate,’星期一’),LAST_DAY(hiredate)
FROM emp
WHERE job<>’MANAGER’;


显式数据类型转换
通常是在字符类型、日期类型、数值类型之间进行显式转
换。主要有3个显式转换函数:
• TO_CHAR
• TO_NUMBER
• TO_DATE


–to_char 用于日期类型
select to_char(sysdate) from dual; –25-7月 -18 默认DD-MON-RR格式
select to_char(sysdate,’YYYY”年”MM”月”DD”日” hh24:mi:ss’) from dual;–错误 日期格式无法识别,需要给每个中文字符加上”“双引号 2018年07月25日 11:01:56
select to_char(sysdate,’YYYY-MM-DD hh24:mi:ss’) from dual;–2018-07-25 11:02:03
select to_char(sysdate,’YYYY/MM/DD hh24:mi:ss’) from dual;–2018/07/25 11:02:03

select
to_char(sysdate,’YEAR’), –TWENTY EIGHTEEN
to_char(sysdate,’MONTH’), –7月
to_char(sysdate,’DAY’), –星期三
to_char(sysdate,’DY’), –星期三
to_char(sysdate,’AM’), –上午
to_char(sysdate,’YYYY/MM/DD hh12:mi:ss am day’)
from dual;

–to_char 用于数值类型
–注意:进行数字类型到字符型转换时,格式中的宽度一定要超过实际列宽度,否则会显示为###
select to_char(123345789.123) from dual;–123345789.123
select to_char(123345789.126,’ 999 , 999 , 999.99 ) f r o m d u a l ; 123,345,789.13
select to_char(123345789.126,’L999,999,999.99’) from dual;–¥123,345,789.13
select to_char(123345789.126,’L999,999,999,999,999.99’) from dual;–#####################
select to_char(123.456,’L0999,999,999.99’) from dual;

–to_number 将字符串转换为数值
select ‘123.456’+100 from dual; –223.456 隐式转换,将字符串默认转换为数值计算
select to_number(‘123.456’)+100 from dual; –223.456 显示转换

select ‘123.456a’+100 from dual; – 错误 无效数字,不能包含非数字字符
select to_number(‘123.456a’)+100 from dual; – 错误 无效数字,不能包含非数字字符

–to_date 将字符串转换为日期
select to_date(‘2018-07-25’) from dual; –错误 文字与格式字符串不匹配
select to_date(‘25-7月-18’) from dual; –只带一个参数,格式必须为DD-MON-RR格式
select to_date(‘2018-07-25’,’YYYY-MM-DD’) from dual;
select to_date(‘2018/07/25’,’YYYY/MM/DD’) from dual;
select to_date(‘2018年07月25日’,’YYYY”年”MM”月”DD”日”’) from dual;– 错误 日期格式不能识别,需要给每个中文字符加上”“双引号

SELECT SYSDATE,TO_CHAR(SYSDATE,’YYYY-MONTH-DD DAY HH:MM:SS’) FROM DUAL;–YY-MM-DD HH:MM:SS


–通用函数

–nvl(参数一,参数二) 如果参数一为null,取参数二的值,否则,取参数一本身的值
select ename,comm,nvl(comm,0) from emp;

–nvl2(参数一,参数二,参数三) 如果参数一位null,取参数三的值,否则,取参数二的值
select nvl2(null,’男’,’女’) from dual;–’女’
select nvl2(‘M’,’男’,’女’) from dual; – ‘男’

–nullif(参数一,参数二) 如果参数一等于参数二,返回null,否则,返回第一个参数的值
select nullif(10,10) from dual;–null
select nullif(10,20) from dual;–10

–coalesce(参数一,参数二,[参数三…..]) 返回不为null的参数值
select ename,comm,coalesce(comm,null,null,’为null’) from emp;–错误 数据类型不一致
select ename,comm,coalesce(comm,null,null,0) from emp;

–case..when..then..else..end
select ename,job,sal,deptno,
case deptno
when 10 then ‘软件开发事业部’
when 20 then ‘测试部’
when 30 then ‘实施部’
else ‘外卖部’
end
from emp;

–decode
select ename,job,sal,deptno,decode(deptno,10,’软件开发事业部’,20,’测试部’,30,’实施部’,’外卖部’) from emp;
select decode(sex,’M’,’男’,’F’,’女’,’不详’) from [某表];

–函数嵌套(可以嵌套任意多层)
select ename, concat(ename,nvl(to_char(mgr), ‘No Manager’)) from emp where mgr is null;–KING

–练习:7.在员工表中查询出员工的工资,并计算应交税款:
–如果工资小于1000,税率为0,
–如果工资大于等于1000并小于2000,税率为10%,
–如果工资大于等于2000并小于3000,税率为15%,
–如果工资大于等于3000,税率为20%。
/*select ename, job,sal,lpad(sal, 4, ‘0’),substr(lpad(sal, 4, ‘0’), 1, 1),
decode(substr(lpad(sal, 4, ‘0’), 1, 1), – 补0补够4位数,再截取第一位
0,0,
1,sal * 0.1,
2,sal * 0.15,
sal * 0.2) 税
from emp;*/
–方式一:
SELECT E.ENAME 员工,E.SAL 员工的工资,
(CASE
WHEN E.SAL < 1000 THEN 0
WHEN E.SAL >= 1000 AND E.SAL < 2000 THEN E.SAL*0.1
WHEN E.SAL >= 2000 AND E.SAL < 3000 THEN E.SAL*0.15
ELSE E.SAL*0.2
END) 应交税款
FROM EMP E;

–方式二:
SELECT E.ENAME 员工,E.SAL 员工的工资,TRUNC(E.SAL/1000),
(CASE TRUNC(E.SAL/1000)
WHEN 0 THEN 0
WHEN 1 THEN E.SAL*0.1
WHEN 2 THEN E.SAL*0.15
ELSE E.SAL*0.2
END) 应交税款
FROM EMP E;

–方式三:
SELECT E.ENAME 员工,E.SAL 员工的工资,
DECODE(TRUNC(E.SAL/1000),0,0,
1,E.SAL*0.1,
2,E.SAL*0.15,E.SAL*0.2) 应交税款
FROM EMP E;

练习
1.显示服务器系统当前时间,格式为2007-10-12 17:11:11(提示:使用to_char函数)
SELECT TO_CHAR(SYSDATE,’YYYY-MONTH-DD HH:mi:ss’) FROM DUAL;
2.显示ename、hiredate 和 雇员开始工作日是星期几,列标签DAY(提示:使用to_char函数)
SELECT ename,TO_CHAR(hiredate,’YYYY”年”MONTH”月”DD”日” DAY’) FROM emp;
3.查询员工姓名,工资,格式化的工资(¥999,999.99) (提示:使用to_char函数)
SELECT ename,sal,TO_CHAR(sal,’L999,999.99’) FROM emp;
4.把字符串2015-3月-18 13:13:13 转换成日期格式,并计算和系统当前时间间隔多少天。 (提示:使用to_date函数)
SELECT SYSDATE-TO_DATE(‘2015-03-18 13:13:13’,’YYYY-MM-DD HH24:mi:SS’) FROM DUAL;

在员工表中查询出员工的工资,并计算应交税款:如果工
0 资小于1000,税率为0,如果工资大于等于1000并小于2000,
税率为10%,如果工资大于等于2000并小于3000,税率为
15%,如果工资大于等于3000,税率为20%。
SELECT sal,CASE TRUNC(sal/1000,0)
WHEN 0 THEN 0
WHEN 1 THEN sal*0.1
WHEN 2 THEN sal*0.15
ELSE sal*0.2
END “应交税费”
FROM emp;
select SUBSTR(ename,3,1) from emp;
SELECT ename FROM emp WHERE NULLIF(SUBSTR(ename,3,1),’A’) IS NULL;

猜你喜欢

转载自blog.csdn.net/qq_34693104/article/details/81365817