更新sql中的RANK()函数

时间:2017-06-12 15:47:18

标签: sql db2 rank dense-rank

我有2个表格,排名不正确,如下所示。是否可以比较这两个表之间的数据,并根据第一个表中可用的数据对其进行排名,并对值中第一个表中的不可用记录进行排名。

表1:

PRODUCT1    LINE1      RANK1
12345       XXXX         1
12345       YYYY         2
12345       ZZZZ         3
34556       GGGG         1 

我的table2目前有以下输出

表2:

PRODUCT2 LINE2 SCORE RANK2 
12345    GGGG  100    1 
12345    JJKJ  90     2 
12345    WEJJ  80     3 
12345    CCCC  70     4 
12345    XXXX  60     5 
12345    YYYY  50     6 
12345    ZZZZ  40     7 
34556    AAAA  90     1 
34556    GGGG  80     2 
34556    HHHH  90     3 
34556    FFFF  80     4

我希望更新后的table2输出如下所示

PRODUCT2 LINE2 SCORE RANK2 
12345    XXXX   70    1 
12345    YYYY   50    2 
12345    ZZZZ   40    3 
12345    GGGG   100   4 
12345    JJKJ   90    5 
12345    WEJJ   80    6 
12345    CCCC   70    7 
34556    GGGG   80    1 
34556    HHHH   90    2 
34556    FFFF   80    3 
34556    AAAA   90    4

查询输出如下所示,

PRODUCT2 LINE2 SCORE RANK2 
12345    XXXX   70    1 
12345    YYYY   50    2 
12345    ZZZZ   40    3 
12345    GGGG   100   4 
12345    JJKJ   90    5 
12345    WEJJ   80    6 
12345    CCCC   70    7 
34556    GGGG   80    1 
34556    HHHH   90    8 
34556    FFFF   80    9 
34556    AAAA   90    10

由于答案中的(SELECT MAX(RANK)FROM TEMP),无论产品编号如何,它都取自temp的最大等级,并将最大数量指定为剩余产品的等级。在这种情况下,7是product1中的最大等级数,因此它为表2中的不可用行分配等级为8,9,10

1 个答案:

答案 0 :(得分:0)

Here you go

WITH TEMP AS (                                                    
    SELECT B.PRODUCT2,                                                
    B.LINE2, B.SCORE,                                                
    ROW_NUMBER() OVER () RANK                                        
    FROM TABLE1 A, TABLE2                                             
    B WHERE A.PRODUCT1 = B.PRODUCT2 AND A.LINE1 = B.LINE2             
)                                                                 
SELECT * FROM TEMP 
UNION                                          
SELECT PRODUCT2, LINE2, SCORE, 
    ROW_NUMBER() OVER () + (SELECT MAX(RANK) FROM TEMP) RANK           
FROM TABLE2 C                                                     
WHERE NOT EXISTS (                                                
    SELECT * FROM TABLE1 WHERE PRODUCT1 = C.PRODUCT2 AND LINE1 = C.LINE2
    ) 
ORDER BY RANK                                                     

Adding answer based on change in question


If you have different products, then while ranking them using rownumber, use Partition. This will rank "within" the partition, product in your case.

WITH TEMP AS (                                                   
    SELECT B.PRODUCT2,                                           
    B.LINE2, B.SCORE,                                            
    ROW_NUMBER() OVER (Partition by PRODUCT2) RANK               
    FROM TABLE1 A, TABLE2                                        
    B WHERE A.PRODUCT1 = B.PRODUCT2 AND A.LINE1 = B.LINE2        
)                                                                
SELECT * FROM TEMP                                               
UNION                                                            
SELECT PRODUCT2, LINE2, SCORE,                                   
    ROW_NUMBER() OVER (Partition by PRODUCT2)                    
+ (SELECT MAX(RANK) FROM TEMP where temp.product2 = C.product2) RANK                              
FROM TABLE2 C                                                    
WHERE NOT EXISTS (                                               
    SELECT * FROM TABLE1 WHERE PRODUCT1 = C.PRODUCT2 AND LINE1 = 
C.LINE2  )                                                       
ORDER BY product2 , RANK