使用SQL根据另一列的值更改来增加计数器

时间:2015-09-17 02:24:27

标签: sql sql-server

我的数据与下面类似。

UID  EventId  Status  
-------------------
1       1       C
1       2       D
1       3       D
1       4       C
1       5       B
2       1       A
2       2       A   
2       3       D    
2       4       C
3       1       D       

我需要创建一个如下所示的status_counter。每次状态发生变化时,状态计数器都会递增。有没有人在做过这样的事情。有人可以帮助我吗?感谢您的帮助。

UID  EventId  Status  Status_Counter
-------------------------------------
1       1       C         1
1       2       D         2
1       3       D         2
1       4       C         3
1       5       B         4
2       1       A         1
2       2       A         1   
2       3       D         2    
2       4       C         3
3       1       D         1

3 个答案:

答案 0 :(得分:2)

使用ROW_NUMBERDENSE_RANK

SQL Fiddle

;WITH Cte AS(
    SELECT *,
        rn = ROW_NUMBER() OVER(PARTITION BY UID ORDER BY EventId)
                - ROW_NUMBER() OVER(PARTITION BY UID, Status ORDER BY EventId)
    FROM tbl
)
SELECT
    UID, EventId, Status,
    Status_Counter = DENSE_RANK() OVER(PARTITION BY UID ORDER BY rn)
FROM Cte
ORDER BY UID, EventId

答案 1 :(得分:1)

逻辑可以封装为不同的累积计数:

select t.*,
       count(distinct status) over (partition by uid order by eventid) as Status_Counter
from table t;

但是,SQL Server并不支持这一点。因此,在SQL Server 2012 +中:

select t.uid, t.eventid, t.status,
       sum(case when lagstatus = status then 0 else 1 end) over (partition by uid order by eventid) as status_counter
from (select t.*, 
             lag(status) over (partition by uid order by eventid) as lagstatus
      from table t
     ) t;

答案 2 :(得分:0)

在更新期间需要执行操作时,更好的工作方式是在更新期间使用触发器。

CREATE TRIGGER update_on_status_change 
ON putYourTableNameHere
FOR UPDATE
AS
DECLATE @event_id
@event_id = SELECT event_id FROM UPDATED
if UPDATE(status)
    BEGIN
        UPDATE otherTableWithCounter SET status_counter += 1 WHERE event_id = @event_id
    END

Theres很多时候我不使用触发器,我本可以犯错误。