列更改时的SQL排名

时间:2015-07-01 13:39:05

标签: sql db2 ranking

我正在研究SQL中的一个问题,我正在尝试根据列的更改时间对列进行排名。

基本上,当前表格如下:

DATE        STATUS
10/18/10    A        
10/16/10    A        
10/14/10    B        
10/12/10    A        

我希望根据日期列对状态列进行适当排名,但仅限于状态列更改时。例如:

 DATE        STATUS   RANK 
 10/18/10    A        1 
 10/16/10    A        1 
 10/14/10    B        2 
 10/12/10    A        3 
 10/10/10    A        3

有关如何解决此问题的任何想法?我玩过RANK()和DENSE_RANK()并且无法获得我想要的输出。感谢。

2 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点。一种简单的方法是使用子查询来计算与当前值不同的值的数量。另一种方法是使用行号的差异。两者都提供了一个组标识符,然后您需要更加努力地获得所需的排名:

select t.date, t.status, dense_rank() over (order by mindate) as ranking
from (select t.*, min(date) over (partition by grp, status) as mindate   
      from (select t.*,
                   (row_number() over (order by date) -
                    row_number() over (partition by status order by date)
                   ) as grp
            from table t
           ) t
     ) t;

根据顺序,您可能需要外部查询中的order by mindate desc

答案 1 :(得分:0)

DB2是支持LAGLEAD OLAP窗口函数的SQL DBMS之一,它可以将当前行中的表达式与同一分区窗口中的其他行进行比较。 RANKDENSE_RANK都不适合您想要的计算(状态更改的运行计数),但可以使用SUM和二进制表达式完成:

WITH StatusHistory( histDate, statusCode ) AS (
    VALUES 
    ( DATE( '2010-10-10' ), 'A' ), 
    ( DATE( '2010-10-12' ), 'A' ),
    ( DATE( '2010-10-14' ), 'B' ), 
    ( DATE( '2010-10-16' ), 'A' ),
    ( DATE( '2010-10-18' ), 'A' )
)
SELECT histDate, 
statusCode, 
SMALLINT( 
    SUM( 
        CASE LAG( statusCode, 1 ) 
           OVER ( ORDER BY histDate DESC) 
        WHEN statusCode 
        THEN 0 
        ELSE 1
        END
    ) OVER ( ORDER BY histDate DESC )
) AS changeSeq
FROM StatusHistory
ORDER BY histDate DESC
;

HISTDATE   STATUSCODE CHANGESEQ
---------- ---------- ---------
10/18/2010 A                  1
10/16/2010 A                  1
10/14/2010 B                  2
10/12/2010 A                  3
10/10/2010 A                  3

5 record(s) selected.