T-SQL:如何为非唯一群组中的项目编号

时间:2016-05-11 14:52:34

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

有一个记录用户登录的表。

列是:

UserID,Date,IsSuccessful(bit)

我需要找到那些有3个以上失败的考生的用户才能连续登录。

我试过了:

select  UserID, Date, IsSuccessful,
        count(*) over ( partition by UserID, IsSuccessful order by Date ) Cnt
from    UserLogins
order   by UserID, Date

Cnt列显示IsSuccessful值的序号,但在组更改时不会重新启动:

UserID, IsSuccessful, Cnt
555, 1, 1
555, 1, 2
555, 1, 3
555, 0, 1
555, 0, 2
555, 1, 4
555, 0, 3
555, 1, 5
555, 1, 6
555, 1, 7
555, 0, 4
555, 0, 5
555, 0, 6
555, 1, 8

我需要的是:

UserID, IsSuccessful, Cnt
555, 1, 1
555, 1, 2
555, 1, 3
555, 0, 1
555, 0, 2
555, 1, 1
555, 0, 1
555, 1, 1
555, 1, 2
555, 1, 3
555, 0, 1
555, 0, 2
555, 0, 3
555, 1, 1

2 个答案:

答案 0 :(得分:4)

您可以使用以下查询:

SELECT UserID, [Date], IsSuccessful,
       ROW_NUMBER() OVER (PARTITION BY UserID, IsSuccessful, grp 
                          ORDER BY [Date]) AS cnt
FROM (
  SELECT UserID, [Date], IsSuccessful,
         ROW_NUMBER() OVER (PARTITION BY UserID 
                            ORDER BY [Date]) -
         ROW_NUMBER() OVER (PARTITION BY UserID, IsSuccessful 
                            ORDER BY [Date]) AS grp
FROM UserLogins) AS t

答案 1 :(得分:2)

另一种解决方案,不太通用,但解决了我的具体任务(连续检测到3次失败):

select  UserID, [Date], IsSuccessful,
        SUM( 1 - CAST(IsSuccessful AS INT) ) OVER( PARTITION BY UserID ORDER BY DATE ROWS BETWEEN 2 PRECEDING AND CURRENT ROW ) AS NumberOfFailures
from    UserLogins
order   by UserID, [Date]