SQL块排名

时间:2018-08-14 09:02:06

标签: sql sql-server sql-server-2012

我敢肯定,答案将是显而易见的,但我无法使这部分sql正常工作。

我有一个表,其中有3列:

User | Date         | AchievedTarget
----------------------------------------

1    |  2018-01-01  | 1

1    | 2018-02-01   | 0

1    | 2018-03-01   | 1

1    | 2018-04-01   | 1

1    | 2018-05-01   | 0

我想根据AchievedTarget列添加如下排名,是否可以通过上表中的数据在下表中创建排名:

 User | Date         | AchievedTarget | Rank
----------------------------------------

1    |  2018-01-01  | 1               | 1

1    | 2018-02-01   | 0               | 1

1    | 2018-03-01   | 1               | 1

1    | 2018-04-01   | 1               | 2

1    | 2018-05-01   | 0               | 1

2 个答案:

答案 0 :(得分:1)

这是一个猜测,基于这实际上是一个差距和孤岛的问题。如果是这样,则生成OP提供的第二个数据集:

CREATE TABLE dbo.TestTable ([User] tinyint, --Avoid using keywords for column names
                            [date] date, --Avoid using datatypes for column names
                            AchievedTarget bit);

GO

INSERT INTO dbo.TestTable ([User],[date],AchievedTarget)
VALUES (1,'20180101',1),
       (1,'20180201',0),
       (1,'20180301',1),
       (1,'20180401',1),
       (1,'20180501',0);
GO
WITH Grps AS(
    SELECT [User],[date],AchievedTarget,
           ROW_NUMBER() OVER (ORDER BY [date]) -
           ROW_NUMBER() OVER (PARTITION BY AchievedTarget ORDER BY [date]) AS Grp
    FROM dbo.TestTable)
SELECT [User],[date],AchievedTarget,
       ROW_NUMBER() OVER (PARTITION BY AchievedTarget, Grp ORDER BY [date]) AS [Rank] --Avoid using keywords for column names
FROM Grps
ORDER BY [date]
GO
DROP TABLE dbo.TestTable;

答案 1 :(得分:0)

其他方法:

with tmp as (
select row_number() over(order by date) ID, *
from  dbo.TestTable
)
select f1.*, NbBefore + 1
from tmp f1
outer apply
(
   select top 1 f2.ID IDLimit from tmp f2 where f2.ID<f1.ID and f2.AchievedTarget<>f1.AchievedTarget
   order by f2.ID desc
) f3
outer apply
(
   select count(*) NbBefore from tmp f4 where f4.ID<f1.ID and f4.ID> f3.IDLimit 
) f5