Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3543364
  • 博文数量: 109
  • 博客积分: 10011
  • 博客等级: 上将
  • 技术积分: 2457
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-18 19:04
文章分类

全部博文(109)

文章存档

2011年(1)

2010年(10)

2009年(36)

2008年(62)

我的朋友

分类: Oracle

2008-04-30 11:20:10

Oracle分析函数的应用

统一认证系统有个新需求:查询系统登录活跃用户。活跃用户是指:在一个登录的最小时间间隔在一个时间范围(比如一天)内的用户。因为在统一认证系统中登录日志表只有登录时间,没有上次登录时间字段,应此必须和上条数据做比较。

可以有以下处理办法:

1:用程序实现,写大量的java代码,如果对于数据量较小的应用可以使用,但是统一认证的登录日志表有千万级的数据,现在要遍历所有数据很效率很低,绝对对不行。(排除)

2:用PL/SQL实现:从当前行得到数据,并"找到"之前以及之后行中的数据。这样可以达到目的,查询的开发与运行会带来很大开销,效率也低。(排除)

3:选用ORACLE分析函数:只需做一次全表遍历,一天SQL语句就能搞定。使用分析函数,简单易行且有效(选择) 


分析函数,最早是从ORACLE8.1.6开始出现的,它的设计目的是为了解决诸如"累计计算","找出分组内百分比","前-N条查询","移动平均数计算""等问题。其实大部分的问题都可以用PL/SQL解决,但是它的性能并不能达到你所期望的效果。分析函数是SQL言语的一种扩充,它并不是仅仅试代码变得更简单而已,它的速度比纯粹的SQL或者PL/SQL更快。现在这些扩展已经被纳入了美国国家标准化组织SQL委员会的SQL规范说明书中。 
Analytic-Function(,,...)
OVER (
 
 
 
)    ORACLE提供了以下分析函数:avg, corr, covar_pop, covar_samp, count, cume_dist, dense_rank, first, first_value, lag, last, last_value, lead, max, min, ntile, percent_rank, percentile_cont, percentile_disc, rank, ratio_to_report, stddev, stddev_pop, stddev_samp, sum, var_pop, var_samp, variance. 在此不一一解释,可以参照《ORACLE9I SQL Reference》,有详细说明。
以下是解决这个问题的SQL语句:
SELECT logonid,username,logontime,
lag(logontime,1,null)  over (partition by username order by logonid ) lastlogin ,
logontime-lag(logontime,1,null)  over (partition by username order by logonid ) days
from logon_log order by username,logonid
1>    lag和lead分析函数:lag(在此列显示的属性-这里是登录时间,上下几条数据,如果上下没有数据显示的字符)
2>    over (partition by username order by logonid ) 按username分组,分组后按照登录ID排序,如果没有order by,分组后的数据是无序的,不符合要求。
3>    与logontime做差可以得到登录时间差。得到了需要的数据。

阅读(1756) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~