SQL Server 2012:有条件地增加计数器用户 ROW_NUMBER()

Shn*_*una 5 sql sql-server row-number

我正在尝试根据特定条件申请ROW_NUMBER()增加计数器。

我的数据如下所示,目标计数器是Prep

    id       DSR    PrepIndicator   Prep
   --------------------------------------
    1662835  -1     1               1
    1662835  14     2               2
    1662835  14     2               3
    1662835  20     2               4
    1667321  -1     1               1
    1667321  30     2               2
    1667321  14     2               3
    1680648  -1     1               1
    1680648  14     2               2
    1680648  60     1               1
    1680648  14     2               2
    1680648  14     2               3
    1683870  -1     1               1
    1683870  12     2               2
    1683870  10     2               3
    1683870  60     1               1
    1683870  7      2               2
Run Code Online (Sandbox Code Playgroud)

PrepIndicator暂时忽略该专栏,我尝试实现的业务逻辑如下:

  • 对于每个 Id,Prep如果 DSR 小于 42,则从 1 开始递增计数器。
  • 如果为 42 或更大,请将准备计数器重置为 1。

实际上PrepIndicator,创建了一个标志来实现这一点,即 if PrepIndicator = 1then Prep = 1。如果PrepIndicator = 2,则增加Prep

如果可能的话,我希望在没有PrepIndicator专栏的情况下实现这一目标。

我如何实现这个有条件的增量ROW_NUMBER()

我试过了

ROW_NUMBER() OVER (PARTITION BY id, PrepIndicator ORDER BY id) 
Run Code Online (Sandbox Code Playgroud)

DSR但当is时它似乎不起作用>= 42

任何建议或帮助都会很棒。谢谢!

max*_*llb 0

首先,您需要明确的排序。仅当您有先前的值时,“递增计数器”才有意义。您可以向表中添加 IDENTITY 列,或使用ROW_NUMBER() OVER ORDER BY(/* your logic here */). 在您的表中,前三列甚至没有唯一值(请参阅 1680648, 14, 2),因此我认为添加 ID 是正确的方法。

为了实现您想要实现的目标,我相信您必须循环执行此操作。如果您使用ROW_NUMBER()您可能希望选择到临时表中。根据您问题的性质,术语计数器表示您将有一个变量。

UPDATE TableA SET rowId = ROW_NUMBER() OVER(ORDER BY id, DSR, PrepIndicator)
Run Code Online (Sandbox Code Playgroud)

那么“条件”似乎表明可以很好地使用CASE

DECLARE @counter INT = 1
DECLARE @row INT = 1
DECLARE @DSR INT

UPDATE TableA SET Prep = @counter
SET @row = (SELECT rowId FROM TableA WHERE rowId > @row)

WHILE EXISTS( SELECT TOP 1 1 FROM TableA WHERE rowId = @row )
BEGIN
    SELECT @DSR = DSR FROM TableA WHERE rowId = @row
    SET @counter = CASE WHEN @DSR < 42 THEN @counter + 1 ELSE 1 END
    UPDATE TableA SET Prep = @counter WHERE rowId = @row
    SET @row = (SELECT rowId FROM TableA WHERE rowId > @row)
END
Run Code Online (Sandbox Code Playgroud)