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)
您可以使用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)
归档时间: |
|
查看次数: |
21504 次 |
最近记录: |