Oracle--分析函数、系统信息函数

1、分析函数

Oracle--分析函数、系统信息函数_第1张图片

create table earnings -- 打工赚钱表
(
  earnmonth varchar2(6), -- 打工月份
  area varchar2(20), -- 打工地区
  sno varchar2(10), -- 打工者编号
  sname varchar2(20), -- 打工者姓名
  times int, -- 本月打工次数
  singleincome number(10,2), -- 每次赚多少钱
  personincome number(10,2) -- 当月总收入
)
然后插入实验数据:

insert into earnings values('200912','北平','511601','大魁',11,30,11*30);
insert into earnings values('200912','北平','511602','大凯',8,25,8*25);
insert into earnings values('200912','北平','511603','小东',30,6.25,30*6.25);
insert into earnings values('200912','北平','511604','大亮',16,8.25,16*8.25);
insert into earnings values('200912','北平','511605','贱敬',30,11,30*11);

insert into earnings values('200912','金陵','511301','小玉',15,12.25,15*12.25);
insert into earnings values('200912','金陵','511302','小凡',27,16.67,27*16.67);
insert into earnings values('200912','金陵','511303','小妮',7,33.33,7*33.33);
insert into earnings values('200912','金陵','511304','小俐',0,18,0);
insert into earnings values('200912','金陵','511305','雪儿',11,9.88,11*9.88);

insert into earnings values('201001','北平','511601','大魁',0,30,0);
insert into earnings values('201001','北平','511602','大凯',14,25,14*25);
insert into earnings values('201001','北平','511603','小东',19,6.25,19*6.25);
insert into earnings values('201001','北平','511604','大亮',7,8.25,7*8.25);
insert into earnings values('201001','北平','511605','贱敬',21,11,21*11);

insert into earnings values('201001','金陵','511301','小玉',6,12.25,6*12.25);
insert into earnings values('201001','金陵','511302','小凡',17,16.67,17*16.67);
insert into earnings values('201001','金陵','511303','小妮',27,33.33,27*33.33);
insert into earnings values('201001','金陵','511304','小俐',16,18,16*18);
insert into earnings values('201001','金陵','511305','雪儿',11,9.88,11*9.88);
1.sum函数,统计总合
按照月份,统计每個地区的总收入

select earnmonth, area, sum(personincome)
from earnings
group by earnmonth,area;
结果

(2)rollup函数
按照月份,地区统计收入

select earnmonth, area, sum(personincome)
from earnings
group by rollup(earnmonth,area);
Oracle--分析函数、系统信息函数_第2张图片

(3)cube函数
按照月份,地区进行收入总汇总

select earnmonth, area, sum(personincome)
from earnings
group by cube(earnmonth,area)
order by earnmonth,area nulls last;
Oracle--分析函数、系统信息函数_第3张图片

小结:sum是统计求和的函数。
group by 是分组函数,按照earnmonth和area先后次序分组。
以上三例都是先按照earnmonth分组,在earnmonth内部再按area分组,并在area组内统计personincome总合。
group by 后面什么也不接就是直接分组。
group by 后面接 rollup 是在纯粹的 group by 分组上再加上对earnmonth的汇总统计。
group by 后面接 cube 是对earnmonth汇总统计基础上对area再统计。
另外那个 nulls last 是把空值放在最后。

rollup和cube区别:
如果是ROLLUP(A, B, C)的话,GROUP BY顺序
(A、B、C)
(A、B)
(A)
最后对全表进行GROUP BY操作。

如果是GROUP BY CUBE(A, B, C),GROUP BY顺序
(A、B、C)
(A、B)
(A、C)
(A),
(B、C)
(B)
(C),
最后对全表进行GROUP BY操作

4)grouping函数
在以上例子中,是用rollup和cube函数都会对结果集产生null,这时候可用grouping函数来确认
该记录是由哪个字段得出来的
grouping函数用法,带一个参数,参数为字段名,结果是根据该字段得出来的就返回1,反之返回0

select decode(grouping(earnmonth),1,'所有月份',earnmonth) 月份,
       decode(grouping(area),1,'全部地区',area) 地区, sum(personincome) 总金额
from earnings
group by cube(earnmonth,area)
order by earnmonth,area nulls last;
Oracle--分析函数、系统信息函数_第4张图片

(5)rank() over开窗函数
按照月份、地区,求打工收入排序

select earnmonth 月份,area 地区,sname 打工者, personincome 收入, 
       rank() over (partition by earnmonth,area order by personincome desc) 排名
from earnings;
Oracle--分析函数、系统信息函数_第5张图片

(6)dense_rank() over开窗函数
按照月份、地区,求打工收入排序2

select earnmonth 月份,area 地区,sname 打工者, personincome 收入, 
       dense_rank() over (partition by earnmonth,area order by personincome desc) 排名
from earnings;
Oracle--分析函数、系统信息函数_第6张图片

(7)row_number() over开窗函数
按照月份、地区,求打工收入排序3

select earnmonth 月份,area 地区,sname 打工者, personincome 收入, 
       row_number() over (partition by earnmonth,area order by personincome desc) 排名
from earnings;
Oracle--分析函数、系统信息函数_第7张图片

通过(5)(6)(7)发现rank,dense_rank,row_number的区别:
结果集中如果出现两个相同的数据,那么rank会进行跳跃式的排名,
比如两个第二,那么没有第三接下来就是第四;
但是dense_rank不会跳跃式的排名,两个第二接下来还是第三;
row_number最牛,即使两个数据相同,排名也不一样。

(8)sum累计求和
根据月份求出各个打工者收入总和,按照收入由少到多排序

select earnmonth 月份,area 地区,sname 打工者, 
       sum(personincome) over (partition by earnmonth,area order by personincome) 总收入
from earnings;
Oracle--分析函数、系统信息函数_第8张图片

(9)max,min,avg和sum函数综合运用
按照月份和地区求打工收入最高值,最低值,平均值和总额

select distinct earnmonth 月份, area 地区,
       max(personincome) over(partition by earnmonth,area) 最高值,
       min(personincome) over(partition by earnmonth,area) 最低值,
       avg(personincome) over(partition by earnmonth,area) 平均值,
       sum(personincome) over(partition by earnmonth,area) 总额
from earnings;

(10)lag和lead函数
求出每个打工者上个月和下个月有没有赚钱(personincome大于零即为赚钱)

select earnmonth 本月,sname 打工者,
       lag(decode(nvl(personincome,0),0,'没赚','赚了'),1,0) over(partition by sname order by earnmonth) 上月,
       lead(decode(nvl(personincome,0),0,'没赚','赚了'),1,0) over(partition by sname order by earnmonth) 下月
from earnings;
Oracle--分析函数、系统信息函数_第9张图片

说明:Lag和Lead函数可以在一次查询中取出某个字段的前N行和后N行的数据(可以是其他字段的数据,比如根据字段甲查询上一行或下两行的字段乙),原来没有分析函数的时候采用子查询方法,但是比较麻烦,惭愧,我用子查询有的还查不出来呢。
语法如下:

lag(value_expression [,offset] [,default]) over ([query_partition_clase] order_by_clause);
lead(value_expression [,offset] [,default]) over ([query_partition_clase] order_by_clause);
其中:
value_expression:可以是一个字段或一个内建函数。
offset是正整数,默认为1,指往前或往后几点记录.因组内第一个条记录没有之前的行,最后一行没有之后的行,
default就是用于处理这样的信息,默认为空。

 
再讲讲所谓的开窗函数,依本人遇见,开窗函数就是 over([query_partition_clase] order_by_clause)。比如说,我采用sum求和,rank排序等等,但是我根据什么来呢?over提供一个窗口,可以根据什么什么分组,就用partition by,然后在组内根据什么什么进行内部排序,就用 order by。

-----------------------------------------------------------------------------------------------------

2、系统函数
sys_context()系统函数。第一个参数为'USERENV',是固定的,第二个参数也是固定的,但是是多选固定,可选的值如下所示:

select sys_context('USERENV','AUTHENTICATION_TYPE') from dual;--用户的认证类型
select sys_context('USERENV','AUTHENTICATION_DATA') from dual;--未知
select sys_context('USERENV','BG_JOB_ID') from dual;--当前指定id的会话是否为oracle后台程序建立,不是则返回null
select sys_context('USERENV','CLIENT_INFO') from dual;--通过dbms_application_info包可以存储高达64字节的用户会话信息
select sys_context('USERENV','CURRENT_SCHEMA') from dual;--默认的schema将被当做当前的schema。当在当前会话中使用ALTER SESSION SET CURRENT_SCHEMA语句的时候,它的查询返回值将被改变

select sys_context('USERENV','CURRENT_SCHEMAID') from dual;--当前schema的id
select sys_context('USERENV','CURRENT_USER') from dual;--当前的登陆用户
select REPLACE(SUBSTR(sys_context('USERENV','HOST'),1,30),'\',':') from dual;--当前会话主机操作系统名
select sys_context('USERENV','CURRENT_USERID') from dual;--当前登陆的用户的id
select sys_context('USERENV','DB_DOMAIN') from dual;--为数据库的域指定初始化参数
select sys_context('USERENV','DB_NAME') from dual;--数据库实例名
select sys_context('USERENV','ENTRYID') from dual;--可用的审计标示符。不能再分布式sql语句中使用此选项。使用USERENV关键字必须置AUDIT_TRAIL的初始化参数为真。

select sys_context('USERENV','EXTERNAL_NAME') from dual;--数据库用户的扩展名
select sys_context('USERENV','FG_JOB_ID') from dual;--返回作业id当此会话是客户端进程创建。否则,返回null
select sys_context('USERENV','INSTANCE') from dual;--当前数据库实例的标示id

select sys_context('USERENV','ISDBA') from dual;--当前用户是否是以dba身份登录
select sys_context('USERENV','LANG') from dual;--iso对‘LANGUAGE’的简称,查询的参数比“LANGUAGE”短
select sys_context('USERENV','LANGUAGE') from dual;--结果为当前数据库使用的存储语言,跟上面查询意义一样
select sys_context('USERENV','NETWORK_PROTOCOL') from dual;--用于通信的网络协议
select sys_context('USERENV','NLS_CALENDAR') from dual;--当前会话使用的,格林尼治时间
select sys_context('USERENV','NLS_CURRENCY') from dual;--本地化的货币符,如人民币为¥,美元符为$
select sys_context('USERENV','NLS_DATE_FORMAT') from dual;--当前使用的日期格式,一般中国为dd-mon-rr
select sys_context('USERENV','NLS_DATE_LANGUAGE') from dual;--表示日期的语言,如中文简体SIMPLIFIED CHINESE

select sys_context('USERENV','NLS_TERRITORY') from dual;--数据库服务器所在区域,如中国CHINA
select sys_context('USERENV','OS_USER') from dual;--操作系统的用户名
select sys_context('USERENV','PROXY_USER') from dual;--是否使用代理用户。否返回null
select sys_context('USERENV','PROXY_USERID') from dual;--代理用户id
select sys_context('USERENV','SESSION_USER') from dual;--当前认证的数据库用户名
select sys_context('USERENV','SESSION_USERID') from dual;--当前认证的数据库用户名id
select sys_context('USERENV','SESSIONID') from dual;--当前会话id
select sys_context('USERENV','TERMINAL') from dual;--操作系统用户组
select sys_context('USERENV','IP_ADDRESS') from dual;-- 当前会话主机ip
select sys_context('USERENV','HOST') from dual;--当前会话主机操作系统名





你可能感兴趣的:(Oracle,oracle,分析函数,系统函数)