sql查询解释:oracle的rank和partition
Posted
技术标签:
【中文标题】sql查询解释:oracle的rank和partition【英文标题】:Explanation of sql query : Rank and partition oracle 【发布时间】:2015-06-11 05:50:24 【问题描述】:我正在使用 oracle 数据库并且卡在这个查询上,我不明白它是如何工作的,我已经删除了所有不必要的信息并且查询已经归结为:
select RANK () OVER (PARTITION BY A_pk ORDER BY B_pk DESC) as column from Table_C
有人能解释一下这是如何工作的吗?
【问题讨论】:
本教程很好地解释了窗口函数:postgresql.org/docs/current/static/tutorial-window.html 我正在使用 oracle db,postgresql 的概念也适用于 oracle 吗? @a_horse_with_no_name 是的,是ANSI SQL 99标准函数 【参考方案1】:假设你有下表:
SELECT *,
ROW_NUMBER() OVER(PARTITION BY col1 ORDER BY col2) AS [ROW_NUMBER],
RANK() OVER(PARTITION BY col1 ORDER BY col2) [RANK],
DENSE_RANK() OVER(PARTITION BY col1 ORDER BY col2) [DENSE_RANK]
FROM SomeTable
col1 col2 | ROW_NUMBER RANK DENSE_RANK
1 1 | 1 1 1
1 1 | 2 1 1
1 5 | 3 3 2
1 5 | 4 3 2
1 9 | 5 5 3
1 9 | 6 5 3
2 1 | 1 1 1
2 1 | 2 1 1
2 1 | 3 1 1
2 3 | 4 4 2
2 3 | 5 4 2
ROW_NUMBER:
这些是window ranking
函数。这意味着当您按某个列进行分区时,函数在该分区的窗口中起作用。想象一下:
col1 col2
/*------*\
|1 1|
|1 1|
|1 5| <--window 1
|1 5|
|1 9|
|1 9|
\*------*/
/*------*\
|2 1|
|2 1|
|2 1| <--another window 2
|2 3|
|2 3|
\*------*/
当窗口改变时,一切都会重置!因此,对于ROW_NUMBER
,您按col2
订购并按该顺序分配增量编号。当窗口更改时,功能重置并从1
开始。
排名:
此函数将计算col2
的值小于当前行中col2
的值加1 的行数。例如在window 1
中col2 = 5
的行有2 行col2 = 1
,所以2 + 1 = 3
。对于 col2 = 9
的行,有 4 行,所以 4 + 1 = 5
。
DENSE_RANK:
它与RANK
相同,但它计算前面的 DISTINCT 值!例如,对于 col2 = 9
的行,col2 = 1 and 5
有 2 个不同的值,所以 2 + 1 = 3
【讨论】:
【参考方案2】:根据A_pk
列中的值将表格划分为“windows”:
A_pk | B_pk
develop | 11
develop | 7
develop | 9
develop | 8
develop | 10
*** window ***
personnel | 5
personnel | 2
*** window ***
sales | 3
sales | 1
sales | 4
按B_pk desc
订购每个“窗口”:
A_pk | B_pk
develop | 11
develop | 10
develop | 9
develop | 8
develop | 7
*** window ***
personnel | 5
personnel | 2
*** window ***
sales | 4
sales | 3
sales | 1
按窗口返回每行的排名(它所在的“位置”):
1
2
3
4
5
*** window ***
1
2
*** window ***
1
2
3
【讨论】:
【参考方案3】:让我们通过对 SCOTT 模式中的示例 EMP 表的这个简单查询来理解:
SQL> SELECT empno,
2 deptno,
3 sal,
4 rank() over(partition BY deptno order by sal) rn
5 FROM emp;
EMPNO DEPTNO SAL RN
---------- ---------- ---------- ----------
7934 10 1300 1
7782 10 2450 2
7839 10 5000 3
7369 20 800 1
7876 20 1100 2
7566 20 2975 3
7788 20 3000 4
7902 20 3000 4
7900 30 950 1
7654 30 1250 2
7521 30 1250 2
7844 30 1500 4
7499 30 1600 5
7698 30 2850 6
14 rows selected.
SQL>
RANK 函数是一个内置的分析函数,用于对一组行中的记录进行排名。窗口中的 PARTITION BY 子句对行进行分组,而 ORDER BY 子句告诉如何排名,即每个组中的哪一行将保持第一个排名,然后按该顺序将下一个排名分配给下一行。
集团 排序 分配排名因此,在上面的示例中,行按部门分组,按薪水排序。在每个组中,从最低工资(升序)开始分配排名。当出现平局时,排名不会增加,但是,值发生变化的下一行不会有连续的顺序。这就是这里发生的事情:
7654 30 1250 2
7521 30 1250 2
7844 30 1500 4
排名不连续,因为工资1250
的两行之间存在平局。要保持序列连续,您需要使用 DENSE_RANK。
【讨论】:
以上是关于sql查询解释:oracle的rank和partition的主要内容,如果未能解决你的问题,请参考以下文章
Oracle用户登录和连接查询特殊排序over()rank()decode() case whenUNION/UNION ALL