找回密码
 注册账号

QQ登录

只需一步,快速开始

手机号码,快捷登录

手机号码,快捷登录

初学者课程:T3自学|T6自学|U8自学软件下载课件下载工具下载资料:通资料|U8资料|NC|培训|年结积分规则 | 使用常见问题Q&A
知识库:U8 | | NC | U9 | OA | 政务U8|U9|NCC|NC65|NC65客开|NCC客开新手必读 | 任务 | 快速增金币用友QQ群[微信群]
查看: 3522|回复: 1

[数据库知识] oracle中利用函数获得top n的结果集

[复制链接]
发表于 2007-3-27 20:31:01 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册账号

×
oracle中利用函数获得top n的结果集

    RANK(),DENSE_RANK()是oracle8i 的两个有趣的分析函数, 可以用来解决top-N问题.
两个函数的区别可以从下面例子中看出:

create table emp
(Empno varchar2(10),
Ename varchar2(10),
Job varchar2(10),
Mgr varchar2(10),
Sal varchar2(10)
);

insert into emp values('Empno1','Ename1','Job1','Mgr1','1');
insert into emp values('Empno2','Ename2','Job2','Mgr2','2');
insert into emp values('Empno3','Ename3','Job3','Mgr3','3');
insert into emp values('Empno4','Ename4','Job4','Mgr4','4');
insert into emp values('Empno5','Ename5','Job5','Mgr5','5');
insert into emp values('Empno6','Ename6','Job6','Mgr6','6');
insert into emp values('Empno7','Ename7','Job7','Mgr7','4');
insert into emp values('Empno8','Ename8','Job8','Mgr7','5');
insert into emp values('Empno9','Ename9','Job9','Mgr7','6');
commit;

SELECT Empno, Ename, Job, Mgr, Sal,
RANK() OVER (ORDER BY SAL Desc NULLS LAST) AS Rank,
DENSE_RANK() OVER (ORDER BY SAL Desc NULLS LAST) AS Drank
FROM Emp
ORDER BY SAL Desc NULLS LAST;

EMPNO ENAME JOB MGR SAL RANK DRANK
---------- ---------- ---------- ---------- ---------- ---------- ----------
Empno6 Ename6 Job6 Mgr6 6 1 1
Empno9 Ename9 Job9 Mgr7 6 1 1
Empno5 Ename5 Job5 Mgr5 5 3 2
Empno8 Ename8 Job8 Mgr7 5 3 2
Empno4 Ename4 Job4 Mgr4 4 5 3
Empno7 Ename7 Job7 Mgr7 4 5 3
Empno3 Ename3 Job3 Mgr3 3 7 4
Empno2 Ename2 Job2 Mgr2 2 8 5
Empno1 Ename1 Job1 Mgr1 1 9 6

结果是不是很奇妙?如果我们自己写sql 实现,是需要一些技巧的。

1.利用RANK()可以实现top-N 问题

下面这个sql 可以显示,最大的几个Sal,相同Sal 的记录也同样显示.

SELECT Empno, Ename, Job, Mgr, Sal
FROM
(SELECT Empno, Ename, Job, Mgr, Sal,
RANK() OVER (ORDER BY SAL Desc NULLS LAST) AS Emp_Rank
FROM Emp
ORDER BY SAL Desc NULLS LAST)
WHERE Emp_Rank = 1;

EMPNO ENAME JOB MGR SAL
---------- ---------- ---------- ---------- ----------
Empno6 Ename6 Job6 Mgr6 6
Empno9 Ename9 Job9 Mgr7 6

SELECT Empno, Ename, Job, Mgr, Sal
FROM
(SELECT Empno, Ename, Job, Mgr, Sal,
RANK() OVER (ORDER BY SAL Desc NULLS LAST) AS Emp_Rank
FROM Emp
ORDER BY SAL Desc NULLS LAST)
WHERE Emp_Rank < 4;

EMPNO ENAME JOB MGR SAL
---------- ---------- ---------- ---------- ----------
Empno6 Ename6 Job6 Mgr6 6
Empno9 Ename9 Job9 Mgr7 6
Empno5 Ename5 Job5 Mgr5 5
Empno8 Ename8 Job8 Mgr7 5

SELECT Empno, Ename, Job, Mgr, Sal
FROM
(SELECT Empno, Ename, Job, Mgr, Sal,
RANK() OVER (ORDER BY SAL Desc NULLS LAST) AS Emp_Rank
FROM Emp
ORDER BY SAL Desc NULLS LAST)
WHERE Emp_Rank < 3;

EMPNO ENAME JOB MGR SAL
---------- ---------- ---------- ---------- ----------
Empno6 Ename6 Job6 Mgr6 6
Empno9 Ename9 Job9 Mgr7 6

2.利用RANK()可以实现top(n,m)问题.

SELECT Empno, Ename, Job, Mgr, Sal
FROM
(SELECT Empno, Ename, Job, Mgr, Sal,
RANK() OVER (ORDER BY SAL Desc NULLS LAST) AS Emp_Rank
FROM Emp
ORDER BY SAL Desc NULLS LAST)
WHERE Emp_Rank > 3 and Emp_Rank < 6;

EMPNO ENAME JOB MGR SAL
---------- ---------- ---------- ---------- ----------
Empno4 Ename4 Job4 Mgr4 4
Empno7 Ename7 Job7 Mgr7 4
发表于 2007-11-25 15:38:11 | 显示全部楼层
值得研究,谢谢楼主提供
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

QQ|站长微信|Archiver|手机版|小黑屋|用友之家 ( 蜀ICP备07505338号|51072502110008 )

GMT+8, 2024-11-22 13:40 , Processed in 0.051599 second(s), 9 queries , Gzip On, Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表