利用Oracle内置分析函数进行高效统计汇总(2)
2009-07-02 16:43
519 查看
问题5 求按登记注册类型多个层次划分的单位个数小计和总计
例如要得出如下的结果:
代码 登记注册类型 家数
------ --------------------------------------- ---------
100 内资企业 61920
110 国有企业 1365
140 联营企业 476
141 国有联营企业 52
...
200 港、澳、台商投资企业 9004
210 合资经营企业(港或澳、台资) 4454
220 合作经营企业(港或澳、台资) 556
300 外商投资企业 11396
310 中外合资经营企业 5070
320 中外合作经营企业 663
我们有3种方法,都可以完成任务。
方法1
select code 代码 , substrb(' ',1,item_level*2-2)||b.reg_type 登记注册类型, cnt 家数 from
(
(select substr(z01_08,1,1)||'00' code ,count(*) cnt
from cj601
group by substr(z01_08,1,1))
union
(select substr(z01_08,1,2)||'0' code ,count(*) cnt
from cj601
group by substr(z01_08,1,2))
union
(select substr(z01_08,1,3) code ,count(*) cnt
from cj601
group by substr(z01_08,1,3))
)
c, djzclx b where c.code=b.reg_code;
方法2
select code 代码 , substrb(' ',1,item_level*2-2)||b.reg_type 登记注册类型, cnt 家数 from
(
select
case when code3 is not null then code3
when code2<>'0' then code2
else code1
end code,cnt from (
select substr(z01_08,1,1)||'00' code1 , substr(z01_08,1,2)||'0' code2 , substr(z01_08,1,3) code3 ,count(*) cnt
from cj601
group by rollup(substr(z01_08,1,1),substr(z01_08,1,2),substr(z01_08,1,3))
) where code2<>code3 or code3 is null and code1<>'00'
)
c, djzclx b where c.code=b.reg_code
order by 1
;
方法3
select code 代码 , substrb(' ',1,item_level*2-2)||b.reg_type 登记注册类型, cnt 家数 from
(
select
case when code3 is not null then code3
when code2<>'0' then code2
else code1
end code,cnt from (
select substr(z01_08,1,1)||'00' code1 , substr(z01_08,1,2)||'0' code2 , substr(z01_08,1,3) code3 ,sum(cnt) cnt
from (select substr(z01_08,1,3) z01_08,count(*) cnt from cj601 group by substr(z01_08,1,3))
group by rollup(substr(z01_08,1,1),substr(z01_08,1,2),substr(z01_08,1,3))
) where code2<>code3 or code3 is null and code1<>'00'
)
c, djzclx b where c.code=b.reg_code
order by 1
;
上述3种写法都能得出正确的结果,但执行效率有巨大差别,第一种写法最简单,但是使用union要对cj601作了3遍全表扫描,执行效率最低,第2种写法对cj601做rollup分组,让数据库自动求小计和总计,第3种写法先对cj601做分组汇总,对结果集再做rollup分组,让数据库求小计和总计,在数据量中等的时候效率差不多,数据量大的时候,方法3效率更好些,因为rollup分组要处理的记录数更少,而rollup分组比普通分组开销大一些。
Oracle提供的分析函数一共有10多个,但有些专门的统计函数比如求标准差,相关系数,协方差等我们一般用不到,主要用到的是本文提到的RANK, lead, ratio_to_report等,我们如果能够将它们和decode函数,case语句配合,善加利用,就能编写出执行效率高的汇总语句,高效完成统计数据处理任务。更加详细的关于分析函数的信息,请参考资料Oracle9i Data Warehousing Guide 第19章SQL for Analysis in Data Warehouses。
例如要得出如下的结果:
代码 登记注册类型 家数
------ --------------------------------------- ---------
100 内资企业 61920
110 国有企业 1365
140 联营企业 476
141 国有联营企业 52
...
200 港、澳、台商投资企业 9004
210 合资经营企业(港或澳、台资) 4454
220 合作经营企业(港或澳、台资) 556
300 外商投资企业 11396
310 中外合资经营企业 5070
320 中外合作经营企业 663
我们有3种方法,都可以完成任务。
方法1
select code 代码 , substrb(' ',1,item_level*2-2)||b.reg_type 登记注册类型, cnt 家数 from
(
(select substr(z01_08,1,1)||'00' code ,count(*) cnt
from cj601
group by substr(z01_08,1,1))
union
(select substr(z01_08,1,2)||'0' code ,count(*) cnt
from cj601
group by substr(z01_08,1,2))
union
(select substr(z01_08,1,3) code ,count(*) cnt
from cj601
group by substr(z01_08,1,3))
)
c, djzclx b where c.code=b.reg_code;
方法2
select code 代码 , substrb(' ',1,item_level*2-2)||b.reg_type 登记注册类型, cnt 家数 from
(
select
case when code3 is not null then code3
when code2<>'0' then code2
else code1
end code,cnt from (
select substr(z01_08,1,1)||'00' code1 , substr(z01_08,1,2)||'0' code2 , substr(z01_08,1,3) code3 ,count(*) cnt
from cj601
group by rollup(substr(z01_08,1,1),substr(z01_08,1,2),substr(z01_08,1,3))
) where code2<>code3 or code3 is null and code1<>'00'
)
c, djzclx b where c.code=b.reg_code
order by 1
;
方法3
select code 代码 , substrb(' ',1,item_level*2-2)||b.reg_type 登记注册类型, cnt 家数 from
(
select
case when code3 is not null then code3
when code2<>'0' then code2
else code1
end code,cnt from (
select substr(z01_08,1,1)||'00' code1 , substr(z01_08,1,2)||'0' code2 , substr(z01_08,1,3) code3 ,sum(cnt) cnt
from (select substr(z01_08,1,3) z01_08,count(*) cnt from cj601 group by substr(z01_08,1,3))
group by rollup(substr(z01_08,1,1),substr(z01_08,1,2),substr(z01_08,1,3))
) where code2<>code3 or code3 is null and code1<>'00'
)
c, djzclx b where c.code=b.reg_code
order by 1
;
上述3种写法都能得出正确的结果,但执行效率有巨大差别,第一种写法最简单,但是使用union要对cj601作了3遍全表扫描,执行效率最低,第2种写法对cj601做rollup分组,让数据库自动求小计和总计,第3种写法先对cj601做分组汇总,对结果集再做rollup分组,让数据库求小计和总计,在数据量中等的时候效率差不多,数据量大的时候,方法3效率更好些,因为rollup分组要处理的记录数更少,而rollup分组比普通分组开销大一些。
Oracle提供的分析函数一共有10多个,但有些专门的统计函数比如求标准差,相关系数,协方差等我们一般用不到,主要用到的是本文提到的RANK, lead, ratio_to_report等,我们如果能够将它们和decode函数,case语句配合,善加利用,就能编写出执行效率高的汇总语句,高效完成统计数据处理任务。更加详细的关于分析函数的信息,请参考资料Oracle9i Data Warehousing Guide 第19章SQL for Analysis in Data Warehouses。
相关文章推荐
- 利用Oracle内置分析函数进行高效统计汇总
- 20090901_ 利用Oracle内置分析函数进行高效统计汇总
- 利用Oracle内置分析函数进行高效统计汇总
- 利用Oracle内置分析函数进行高效统计汇总(1)
- 利用Oracle内置分析函数进行高效统计汇总
- 利用Oracle内置分析函数进行高效统计汇总
- 利用 Python 进行数据分析(九)pandas 汇总统计和计算
- 利用Python进行数据分析(9) pandas基础: 汇总统计和计算
- Oracle高效的SQL语句之分析函数汇总
- oracle 统计分析函数
- Oracle]高效的SQL语句之分析函数
- 数据库分页大全(oracle利用解析函数row_number高效分页)
- oracle中LAG()和LEAD()等分析统计函数的使用方法(统计月增长率)
- 利用MapReduce对HBase数据进行统计分析
- BMDP为常规的统计分析提供了大量的完备的函数系统,如:方差分析(ANOVA)、回归分析(Regression)、非参数分析(Nonparametric Analysis)、时间序列(Times Series)等等。此外,BMDP特别擅于进行出色的生存分析(Survival Analysis )。许多年来,一大批世界范围内顶级的统计学家都曾今参与过BMDP的开发工作。这不仅使得BMDP的权威性得到
- Oracle分析函数三、基于model函数建设口径统一的统计指标库
- [Oracle]高效的SQL语句之分析函数(四)--lag()/lead()
- 利用Oracle函数及正则表达式进行排序
- oracle中LAG()和LEAD()等分析统计函数的使用方法(统计月增长率)
- 利用统计进行中文分词与词性分析