Oracle函数应用与查询聚合统计

Oracle预定义函数

Oracle数据库系统中定义了很多的函数(预定义)。这些函数能够完成本身特有的数据操作功能,执行效率更高并重复使用。

Oracle中的预定义函数按照对数据的操作执行特征可以分为:

单行函数——对每个记录执行一次

聚合函数(多行函数)——对多个记录行执行一次

单行函数

字符串函数

日期时间函数

数学计算函数

其它特殊函数

字符串操作函数

substr(source,start,[length])提取字符串

instr(source,target,[start],[rank])查找字符串

ltrim(soure);rtrim(source);trim(source)

To_char(date,format)

Lpad(source,length,prefix)左补齐

字符串操作函数(2)

Rpad(source,length,prefix)右补齐

lower(source)转换小写

upper(source)转换大写

initcap(source)首字母变大写

length(source)获取长度

字符串操作函数(3)

replace(source,oldStr,[newStr]) 替换字符串

CONCAT(left,right)连接字符串,使用||可替代此函数

数学计算函数

Oracle中提供的数学函数可以处理日常使用到的大多数数学运算,在使用数学函数时通常应保证被操作的数据是数值类型,如果是字符串则在保证字符串中是数字时可以使用这些数学函数的

ABS函数

ABS函数是计算绝对值函数,参数可以是一个值类型,也可以是字符串类型,如果是字符串类型则必须保证字符序列是数字

ABS(56) --结果返回56

ABS(5.66) --结果返回5.66

ABS(-56) --结果返回56

ABS(-100) --结果返回100

ABS(10s) --出现错误(01722不是数字)

ROUND函数

ROUND(sourceNum.[decimalLen])

decimalLen是可选参数,设置小数点保留位数,如果省略则不保留小数

ROUND(56.36,1) --结果为56.4

ROUND(56.62) --结果为57

特别提示:decimalLen可以去负数,如果是负数则表示精确到小数点前

ROUND(566.62,-2) --结果为600

CEIL函数

CEIL(number)函数有一个参数。该函数将参数向上取整,以获得大于等于该参数的最小整数

select ceil(21.897) --结果为22

select ceil(21.00) --结果为21

select ceil(-21.897) --结果为-21而不是-22

FLOOR函数

ceil函数相反,floor()函数用于返回小于等于某个数值的最大整数

selectfloor(21.897) --结果为21

selectfloor(-21.897) --结果为-22

SIGNSQRT函数

sign(number)返回参数的正负性。若返回值为1,表示该参数大于0;若返回值为-1,表示该参数小于0;若返回值为0,表示该参数等于0

select sign(8) --结果为1

select sign(-8) --结果为-1

select sign(0) --结果为0

sqrt(number)函数也只有一个参数。该函数用于返回参数的平方根

select round(sqrt(2),3) --结果为1.414

powertrunc函数

power函数用于实现数值的乘方运算

power(6,2) --结果为36

trunc函数用于截取部分数字,类似于round函数。与round函数不同的是,该函数不对数值做四舍五入处理,而是直接截取

trunc(2745.175,2) --结果为2745.17

trunc(2745.175,0) --结果为2745

trunc(2745.175),-2 --结果为2700

To_number函数

to_number函数是将给定的数值(字符串类型)转换为值类型

to_number(257.901) --结果为257.901浮点常量

to_number(-257.900) --结果为257.9浮点常量

to_number(257E) --01722无效数字

日期时间函数

to_date

to_timestamp

add_months

last_day

months_between

current_date

current_timestamp

to_date函数

to_date(dateStr,format)将给定的dateStr字符串按照format格式转换为Date类型数据

insertinto person(birth,age)values(to_date(1999-12-20,yyyy-MM-dd),23)

to_Timestamp函数

to_timestamp(dateStr,format)将给定的dateStr字符串按照format格式转换为Timestamp类型

insert into user(regtime)

values(to_timestamp(2018-12-20 13:20:36,yyyy-MM-dd HH24:mi:ss))

add_months函数

此函数将为日期添加特定月份,并获返回新的日期字符串格式

add_months(SYSDATE,6)--如果当前是2018-7-22则返回结果为2019-1-22

提示:如果month参数为负数则在月份中减去这个负数的正数而得到最后日期

last_day()函数将接受一个日期参数。该函数首先获得日期参数所在月的信息,然后获得该月最后一天的日期字符串结果

Last_day(SYSDATE) --如果SYSDATE2018-07-25’则返回结果为’2018-07-31

months_between函数

months_between(date1,date2)

此函数用于获取两个日期所间隔的月数。该函数的返回值是一个实数,如果date1日期晚于date2则返回正数,如果小于则返回负数,相同则返回0,返回值不是天数的差而是月份的差。

months_between(to_date(2017-01-26,yyyy-MM-dd),to_date(2017-01-26,yyyy-MM-dd)) --结果为0

months_between(to_date(2017-05-26,yyyy-MM-dd),to_date(2017-01-26,yyyy-MM-dd)) --结果为4

months_between(to_date(2017-01-26,yyyy-MM-dd),to_date(2017-05-26,yyyy-MM-dd)) --结果为-4

当前系统日期和时间函数

current_date --返回当前系统日期的字符串形式

current_timestamp --返回当前系统日期和时间的字符串形式

systemdate --返回当前系统日期的字符串形式

systemtimestamp --返回当前系统日期和时间的字符串形式  (下面两种用的更频繁)

extract函数

extract函数用来从给定的日期或时间对象中提取日期或时间的部分,如从日期中提取年、月、日;从时间中提取时、分、秒

extract(Year FROM SYSDATE) --提取年

extract(MONTH FROM SYSDATE) --提取月

extract(DAY FROM SYSDATE) --提取日

extract(hour FROM current_timestamp) --提取小时

extract(minute FROM current_timestamp) --提取分钟

extract(second FROM current_timestamp) --提取秒

特殊函数

ascii(number|string)返回给定数值或字符串首字母的ascii数字值

ascii(A) --返回65

ascii(abc) --返回97

chr(number|string)返回给定数值的字母形式

chr(97) --返回小写字母a

chr(65) --返回大写字母A

nvl(obj1,obj2)判断空,如果obj1不为空则返回obj1,如果obj1为空则返回obj2

nvl(3,99) --返回3

val(null,Ki) --返回Ki

nvl2(target,res1,res2)判断空,如果target不为空则返回res1,否则返回res2

nvl(3,99) --返回3

val(null,Ki) --返回Ki

nvl2(target,res1,res2)判断空,如果target不为空则返回res1.否则返回res2

nvl2(‘’,66,aa) --返回aa

nvl2(a,66,88) --返回66

聚合函数

聚合函数又称为多行函数,在对数据库表进行查询时聚合函数对符合要求的多个数据行一起实施聚合逻辑运算,一个聚合函数最终返回一个聚合值

count() 统计数据行条目数

max() 获取最大值

min() 获取最小值

sum() 统计综合

avg() 统计平均数

count()函数

Count(arg)聚合函数实现对给定参数不为空的聚合统计整个符合条件的条目数量

--统计学生人数

SELECT COUNT(ID)FROM students;

--统计有多少学生有电子邮箱号码

SELECT COUNT(email)FROM student;

MAX()Min()函数

MAXMIN聚合函数分别用来统计给定参数在整个数据源记录行中的最大值和最小值

--学生信息中最大年龄和最小年龄

SELECT MAX(age) 最大年龄,MIN(age) 最小年龄 FROM student;

--最高成绩和最低成绩

SELECT MAX(score) 最高分数,MIN(score) 最低分数 FROM scores;

--最小生日和最大生日

SELECT MAX(birth) 最小生日,MIN(birth) 最大生日 FROM student;

Sum()Avg()函数

SUMavg函数用来对数值类型数据进行和运算和平均数统计,并返回最终结果

--计算成绩总和

select SUM(score) FROM scores;

--计算超过60分成绩的平均值

select AVG(score) FROM scores WHERE score > 60

分组聚合统计

Oracle在聚合函数使用数据统计前可以实现先分组然后再聚合计算,Oracle中使用group by进行分组并且支持多列分组

在实现分组聚合过程中Oracle数据库系统也支持对分组后进行筛选;分组后的筛选使用having字句在group by后面实现对分组进行筛选限制。

system--字符串函数的使用
substr(source,start,[length]) --提取子串
select substr('abcacuback',1,5) from dual;
select substr(NAME,1,1) from emp_tab;

instr(source,target,[start],[rank]) --查找目标字符串返回其第一个字母出现的位置
select instr('中国的北京中有个中间人','',2,2) from dual;

ltrim(soure);rtrim(source);trim(source)
select ltrim('   abc   ') from dual;
select rtrim('   abc   ') from dual;
select trim('   abc   ') from dual;

To_char(date,format)

Lpad(source,length,prefix)
select lpad('23',10,'0') from dual;

select lower('AbcDEddFF') from dual; --转换为小写

select upper('AbcDEddFF') from dual; --转换为大写

select initcap('person') from dual; --转换首字母为大写

select length('person') from dual; --转换长度

select concat('我爱你','中国') from dual; --连接字符串

select '我爱你'||'中国' from dual; --连接字符串

--日期函数
--增加减少月份
select add_months(sysdate,10) from dual;
select add_months(sysdate,-5) from dual;

--last_day 函数(获取当前日期月份的最后一天)
select last_day(sysdate) from dual;
select last_day(to_date('2019-2-15','yyyy-mm-dd'))from dual;

--比较月份之间的差
select months_between(SYSDATE,SYSDATE) FROM dual;
select months_between(to_date('2019-12-20','yyyy-MM-dd'),SYSDATE)FROM dual;
select months_between(SYSDATE,to_date('2019-12-20','yyyy-MM-dd'))FROM dual;
select months_between(to_date('2017-12-20','yyyy-MM-dd'),to_date('2019-12-20','yyyy-MM-dd'))FROM dual;

--获取当前系统日期和时间
select current_date from dual;
select sysdate from dual;

select to_char(current_timestamp,'hh24:mi:ss') current_timestamp from dual;
select to_char(systimestamp,'yyyy-mm-dd hh24:mi:ss.ff4') from dual;

--从给定的日期时间数据中提取某个时刻
select extract(year from sysdate) from dual;
select extract(day from sysdate) from dual;
select extract(month from grantdate) from salary where ID=2;
select * from salary;

--特殊函数

select ascii('')from dual;
select chr(65) from dual;

--空判断函数
select nvl(email,NAME) from emp_tab; --如果此员工没有email则查询显示其名字
select NAME||'员工:'||nvl2(email,'有邮箱号码','没有邮箱号码') 是否有邮箱号码 from emp_tab;
select * from emp_tab;

--聚合函数应用
select * from salary;

select MAX(should) 最高应发工资,MIN(should) 最低应发工资,SUM(should) 所有应发工资合计,
AVG(should) 所有应发工资平均值,count(ID) 所有已发放工资总条目数量
FROM salary ;

select MAX(should) 最高应发工资,MIN(should) 最低应发工资,SUM(should) 所有应发工资合计,
AVG(should) 所有应发工资平均值,count(ID) 所有已发放工资总条目数量
FROM salary WHERE salary.emp_id = (select ID FROM emp_tab WHERE NAME = '任盈盈');

--分组聚合统计查询
--按照每个员工的发放薪水记录分别汇总所有应发工资的总额
select e.name 员工名字, SUM(should) 应发工资 from salary s inner join
emp_tab e on e.id = s.emp_id 
group by e.name having avg(should) >4000;
/*任务一
1 利用字符串函数实现emp表查询操作,要求显示部门名称,员工姓名,住址和入职日期并将信息连接成如下所示字符串显示
如 
研发部员工,姓名:XXX, 住在XXX,yyyy-mm-dd 入职*/

select * from emp;
select * from dept;

select d.name||'员工'|| e.name||'住在'||e.address||to_char(e.entrydate,'yyyy-mm-dd')||'入职' from emp e inner join dept d on e.depid = d.id

--2 查询显示姓名是2个字的员工信息;
select * from emp where name like '__'

--3 由于可能录入的赎回,员工姓名前后包含了空格,使用update语句完成将所有员工姓名前后空格去除;
update emp set name = replace(name,' ','');

--4 查询emp表所有字段信息,要求性别如果为1显示为男,如果是0显示为女,可参照case end 查询语句(自行参考互联网示例);
select e.id,e.name,e.birth,e.address,
case
  when e.gender = 0 then ''
  when e.gender = 1 then ''
end
from emp e
 
--5 利用子查询或连接或联合查询实现比较员工“XXX”和“XXX”的生日月份差并必需显示正数;
select months_between((select birth from emp where name = '曾誉'),(select birth from emp where name = '杨过')) from dual

--6 查询显示员工生日要求格式为XX日XX月XX年;
select extract(Year FROM birth)||''||extract(MONTH FROM birth)||''||extract(DAY FROM birth)||'' from emp

--7 查询显示员工信息判断是否有邮箱号码,如果则显示结果为“xxx员工有邮箱号码”否则“xxx员工未注册邮箱号码”;
select NAME||'员工:'||nvl2(email,'有邮箱号码','未注册邮箱号码') 是否有邮箱号码 from emp

--1 查询显示公司所有员工一共有多少人;
select count(ID) from emp;

--2 查询公司所有员工中年龄最大的人信息,包括部门名称及个人信息;
select d.name,e.name from emp e inner join dept d on e.depid = d.id and e.birth = (select MIN(birth) from emp)

--3 查询最早入职公司的员工姓名和地址及性别(男或女显示);
select e.name,e.address,
case
  when e.gender = 0 then ''
  when e.gender = 1 then ''
end
from emp e where e.entrydate = (select MIN(entrydate) from emp)

--4 查询市场部员工年龄最小的人信息,显示生日以及姓名;
select d.name,e.name,e.birth from emp e inner join dept d on e.depid = d.id 
and e.birth = (select MAX(birth) from emp where depid = 'NO100')

--5 查询销售部最大生日和研发部最大生日的月份差,只显示正数;
select ABS(months_between((select MIN(birth) from emp where depid = 'NO200'),
(select MIN(birth) from emp where depid = 'NO300'))) from dual

--6 查询2018-5到2018-8月的所有产品销售总额;
select * from sales;
select sum(price*salquantity) from sales where saldate between to_date('2018-5','yyyy-mm') 
and to_date('2018-8','yyyy-mm');

--7 查询2018-5到2018-8月产品JP数码相机9X和CH掌上宝MI9销售总额差,显示正数;
select ABS((select sum(price*salquantity) from sales where descs in ('商品3','商品4') and (saldate between to_date('2018-5','yyyy-mm') 
and to_date('2018-8','yyyy-mm')))-
(select sum(price*salquantity) from sales where descs in ('商品0','商品1') and (saldate between to_date('2018-5','yyyy-mm') 
and to_date('2018-8','yyyy-mm')))) from dual;

--8 分别统计每个销售人员的全年销售总额;
select sum(price*salquantity),eid from sales group by eid

--9 分别统计每个产品在2018-6的销售总额;
select sum(price*salquantity),descs from sales where saldate between to_date('2018-6-1','yyyy-mm-dd') 
and to_date('2018-6-30','yyyy-mm-dd') group by descs

--10分别统计每个产品每个销售人员在2018-6的销售总额;
select sum(price*salquantity),eid from sales where saldate between to_date('2018-6-1','yyyy-mm-dd') 
and to_date('2018-6-30','yyyy-mm-dd') group by eid
原文地址:https://www.cnblogs.com/zengyu1234/p/15322388.html