SQL Server - 基于集合的方法,用于递增每N条记录

时间:2013-09-12 15:34:09

标签: sql-server increment

使用SQL Server 2008

我正在研究一种将多张发票合并为一张发票的方法。我可以利用现有的索赔调整存储过程,而不是提供发票ID,而是提供与多个发票相关联的批次ID。

此问题的细节允许一些自动化:要分组的发票将始终在其表中相邻,并且组大小在每组批次中保持不变。

我的问题:T-SQL是否提供了一种基于集合(即非循环)的方法,用于每N条记录自动递增“ID”列?

我知道一个非基于集合的方法是使用带有计数器的游标,每当ID%N等于0时,该计数器就会递增。请参阅以下示例,了解每两个记录递增的字段:

    CREATE TABLE #BatchInvnums (id INT PRIMARY KEY IDENTITY, invnum INT, batchID INT)

    INSERT INTO #BatchInvnums (invnum)
    VALUES (178),(543),(724),(809),(164),(276)

    DECLARE @CurrentID INT,  @CurrentInvnum INT, @Counter INT = 0

    DECLARE CurBatchIDSetter CURSOR FORWARD_ONLY FOR
    SELECT ID, invnum
    FROM #BatchInvnums
    ORDER BY ID

    OPEN CurBatchIDSetter
    FETCH NEXT FROM CurBatchIDSetter INTO @CurrentID, @CurrentInvnum

    WHILE @@FETCH_STATUS = 0
    BEGIN
        UPDATE #BatchInvnums
        SET batchID = @Counter
        WHERE invnum = @CurrentInvnum

        IF @CurrentID % 2 = 0
        BEGIN
            SET @Counter = @Counter + 1
        END
        FETCH NEXT FROM CurBatchIDSetter INTO @CurrentID, @CurrentInvnum
    END

    CLOSE CurBatchIDSetter
    DEALLOCATE CurBatchIDSetter

同样,以上是我不想做的事情。我想使用单个更新语句,或者更好的是,在表创建时应用一些属性以实现此效果。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

我认为row_number()可能是解决方案的途径

update #BatchInvnums
set batchID = rn
from
    #BatchInvnums
        inner join
        (select id,
                (ROW_NUMBER()over(order by id)-1) / 2 rn 
         from #BatchInvnums) v
        on v.id = #batchinvnums.id

答案 1 :(得分:0)

如何使用ROW_NUMBER(作为整数,然后是整数除法)。

这样的东西
SELECT *,
(ROW_NUMBER() OVER(ORDER BY ID) - 1)/ 2 RowID
FROM TADA

SQL Fiddle DEMO

这也可以让您确定分区和行号的排序。