Oracle DENSE_RANK()

时间:2017-09-11 17:58:57

标签: sql oracle dense-rank

我正在尝试在Oracle中使用DENSE_RANK()函数,将任意“主键”附加到唯一的数据分组上。我的数据集是过去几天在不同“地点”针对不同“资产”执行的交易清单。数据集由ASSET ASC,DATE ASC预先订购,如下所示。


ASSET       LOCATION        DATE
A           LOC_A       9/1/2017
A          LOC_A        9/1/2017
A          LOC_B        9/5/2017
A          LOC_B        9/7/2017
A          LOC_A        9/11/2017
B          LOC_A        8/22/2017
B          LOC_C        8/25/2017
B          LOC_C        8/26/2017
B          LOC_A        9/2/2017
B          LOC_A        9/3/2017

当我使用DENSE_RANK()OVER(ORDER BY ASSET,LOCATION)时,我得到以下输出:


ASSET       LOCATION        DATE        ACTUAL
A          LOC_A        9/1/2017        1
A          LOC_A        9/1/2017        1
A          LOC_B        9/5/2017        2
A          LOC_B        9/7/2017        2
A          LOC_A        9/11/2017       1
B          LOC_A        8/22/2017       3
B          LOC_C        8/25/2017       4
B          LOC_C        8/26/2017       4
B          LOC_A        9/2/2017        3
B          LOC_A        9/3/2017        3

但是,我正试图找出一种方法来获取此处显示的“EXPECTED”值的值:


ASSET       LOCATION        DATE        ACTUAL      EXPECTED
A          LOC_A        9/1/2017        1          1
A          LOC_A        9/1/2017        1          1
A          LOC_B        9/5/2017        2          2
A          LOC_B        9/7/2017        2          2
A          LOC_A        9/11/2017       1          3
B          LOC_A        8/22/2017       3          4
B          LOC_C        8/25/2017       4          5
B          LOC_C        8/26/2017       4          5
B          LOC_A        9/2/2017        3          6
B          LOC_A        9/3/2017        3          6

非常感谢任何帮助实现这一目标。

我的SQL是

SELECT ASSET, LOCATION, TXNDATE, 
       DENSE_RANK() OVER (ORDER BY ASSET, LOCATION) AS DENSERANK 
FROM TEMPTABLE 
ORDER BY ASSET, TXNDATE 

是的,我得到上面显示的“ACTUAL”结果。

1 个答案:

答案 0 :(得分:0)

您正在寻找assetlocation中的更改。一种方法使用lag()和累积总和:

SELECT ASSET, LOCATION, TXNDATE, 
       SUM(CASE WHEN Asset = prev_asset AND location = prev_location THEN 0
                ELSE 1
           END) OVER (ORDER BY TXNDATE) AS DENSERANK 
FROM (SELECT tt.*,
             LAG(ASSET) OVER (ORDER BY TXNDATE) as prev_asset,
             LAG(LOCATION) OVER (ORDER BY TXNDATE ) as prev_location
      FROM TEMPTABLE 
     ) tt
ORDER BY ASSET, TXNDATE;

Oracle默认为RANGE BETWEEN而不是ROWS BETWEEN。这是您想要的行为,因为您的行具有相同的日期,并且它们都应该被视为相同。