您的位置:首页 > 数据库 > Oracle

利用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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐