向现有行添加序列号

Lee*_*ary 5 sql-server sequence update

我有一个带OrderSequence列的表。该架构大致如下所示:

id 
Name 
OrderSequence
Run Code Online (Sandbox Code Playgroud)

我有一个来自应用程序的 id ["1", "2", "3", "4"] 数组,我想设置 id 以OrderSequence进行排序。我不想遍历应用程序中的行,一次执行 'n' 个 SQL 查询。如何使用存储过程执行此操作?

样本数据

id Name OrderSequence
1  A    0
2  B    0
3  C    0
Run Code Online (Sandbox Code Playgroud)

想要的结果

id Name OrderSequence
1  A    1
2  B    2
3  C    3
Run Code Online (Sandbox Code Playgroud)

Han*_*non 7

您可以使用ROW_NUMBER()@Kin 提到的语法来完成此操作:

USE Tempdb;
CREATE TABLE dbo.testRowNum
(
    ID INT NOT NULL PRIMARY KEY CLUSTERED IDENTITY(1,1)
    , Name VARCHAR(255)
    , SequenceNum INT NULL
);
INSERT INTO testRowNum (Name) VALUES ('A'), ('B'), ('C');

SELECT *
FROM dbo.testRowNum;

UPDATE dbo.testRowNum
SET SequenceNum = x.RowNum
FROM dbo.testRowNum 
    INNER JOIN (SELECT ID, ROW_NUMBER() OVER (ORDER BY ID) AS RowNum FROM dbo.testRowNum) x ON testRowNum.ID = x.ID
WHERE SequenceNum IS NULL;

SELECT *
FROM dbo.testRowNum;
Run Code Online (Sandbox Code Playgroud)

输出:

输出

如果您只想更新某些行,则可以使用表变量(如果要更新很多行,则可以使用 #temp 表),如下所示:

DECLARE @IDsToUpdate TABLE
(
    ID INT
);

INSERT INTO @IDsToUpdate VALUES (1),(3);

UPDATE dbo.testRowNum
SET SequenceNum = x.RowNum
FROM dbo.testRowNum 
    INNER JOIN (
        SELECT t.ID
            , ROW_NUMBER() OVER (ORDER BY t.ID) AS RowNum 
        FROM dbo.testRowNum t
            INNER JOIN @IDsToUpdate i ON t.ID = i.ID
        ) x ON testRowNum.ID = x.ID
WHERE SequenceNum IS NULL;
Run Code Online (Sandbox Code Playgroud)

上面的示例产生以下输出:

输出


改进(基于Daniel Hutmacher的建议)避免了连接并导致更有效的查询计划(无连接或万圣节保护):

WITH Numbered AS
(
    SELECT 
        SequenceNum,
        RowNum =
            ROW_NUMBER() OVER (
                ORDER BY ID)
    FROM dbo.testRowNum
)
UPDATE Numbered
SET SequenceNum = RowNum;
Run Code Online (Sandbox Code Playgroud)

执行计划

或者,在使用@IDsToUpdate表格时:

WITH Numbered AS
(
    SELECT 
        SequenceNum,
        RowNum =
            ROW_NUMBER() OVER (
                ORDER BY ID)
    FROM dbo.testRowNum
    WHERE EXISTS
    (
        SELECT * 
        FROM @IDsToUpdate AS I
        WHERE I.ID = dbo.testRowNum.ID
    )
)
UPDATE Numbered
SET SequenceNum = RowNum;
Run Code Online (Sandbox Code Playgroud)