我正在研究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()并且无法获得我想要的输出。感谢。
答案 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是支持LAG
和LEAD
OLAP窗口函数的SQL DBMS之一,它可以将当前行中的表达式与同一分区窗口中的其他行进行比较。 RANK
和DENSE_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.