sql查询的解释:排名和分区oracle

时间:2015-06-11 05:50:25

标签: sql oracle rank window-functions

我正在使用oracle数据库并且坚持这个查询,我不理解这是如何工作的,我已经删除了所有不必要的信息,并且查询已经归结为:

 select RANK () OVER (PARTITION BY A_pk ORDER BY B_pk DESC) as column from Table_C

有人可以解释这是如何工作的吗?

3 个答案:

答案 0 :(得分:2)

假设您有下表:

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开始。

<强> RANK:

此函数将计算col2的值小于当前行的col2的值加1的行数。例如,window 1中的行col2 = 5 col2 = 1有2行,所以2 + 1 = 3。对于col2 = 9行,有4行,所以4 + 1 = 5

<强> DENSE_RANK:

它与RANK相同,但它在 DISTINCT 值之前计算!例如,对于包含col2 = 9的行,有col2 = 1 and 5的2个不同值,因此2 + 1 = 3

答案 1 :(得分:0)

  1. 根据A_pk列中的值将表格划分为“窗口”:

     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
    
  2. 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
    
  3. 按窗口返回每行的排名(它所在的“地点”):

    1
    2
    3
    4 
    5
    *** window ***
    1
    2
    *** window ***
    1
    2
    3
    

答案 2 :(得分:0)

让我们理解这个关于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 子句告诉如何排名,即每组中哪一行将保持第一等级然后将下一个等级分配给该顺序中的下一行。

  • GROUP
  • SORT
  • 分配等级

因此,在上面的示例中,行按部门分组,按薪水排序。在每个组中,从最低薪水(升序)开始分配等级。当存在平局时,等级不会增加,但是,具有值变化的紧邻的下一行将不具有连续的序列。这就是这里发生的事情:

7654         30       1250          2
7521         30       1250          2
7844         30       1500          4

排名不是连续的,因为薪水1250的两行之间存在平局。要保持序列连续,您需要使用 DENSE_RANK