2017-09-11 132 views
1

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


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  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 

不过,我试图找出一种方式来获得价值在这里显示的“预期”值:


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 

,是的,我正在上面显示的 “实际” 的结果。

+0

你不应该得到这样的结果。你确定你没有使用'PARTITION BY'吗? – Lamak

+0

我的SQL是SELECT ASSET,LOCATION,TXNDATE,DENSE_RANK()OVER(ORDER BY ASSET,LOCATION)as DENSERANK TEMPTABLE ORDER BY ASSET,TXNDATE和yes,我得到上面显示的“ACTUAL”结果。 – Nathan

回答

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; 

甲骨文默认为RANGE BETWEEN而非ROWS BETWEEN。这是你想要的行为,因为你有具有相同日期的行,并且他们都应该被视为相同。

+0

这是Oracle解决方案吗?按照原样使用你的SQL,由于“RANGE BETWEEN UNBOUNDED AND CURRENT ROW”子句,我得到一个语法错误。范围内的数据库是Oracle 11g。 – Nathan

+0

没关系,当我删除“RANGE BETWEEN UNBOUNDED AND CURRENT ROW”子句查询工作正常并返回结果。这与我的期望值不一样,但它确实为ASSET/LOCATION中的每个独特变化提供了一个独特的值,这正是我所期待的。谢谢! – Nathan

+0

@Nathan。 。 。无论如何,'RANGE BETWEEN'是Oracle的默认值,所以不需要。 –