SQL Server:使用ORDER BY更新表

jer*_*eth 42 sql-server

我想知道在更新表时是否有使用order by子句的方法.我正在更新表并设置一个连续的数字,这就是更新顺序很重要的原因.使用以下sql语句,我能够在不使用游标的情况下解决它:

DECLARE @Number INT = 0

UPDATE Test
SET @Number = Number = @Number +1
Run Code Online (Sandbox Code Playgroud)

现在我想要做的是这样的order by子句:

 DECLARE @Number INT = 0

 UPDATE Test
 SET @Number = Number = @Number +1
 ORDER BY Test.Id DESC
Run Code Online (Sandbox Code Playgroud)

我读过:如何使用ms sql更新和订购此问题的解决方案无法解决排序问题 - 它们只是过滤了应用更新的项目.

小心,马丁

Mar*_*ith 54

没有.

没有记录100%支持的方式.有一种方法有时用于计算称为" 古怪更新 "的运行总计,这表明如果满足某些条件,它可能按聚集索引的顺序更新,但据我所知,这完全依赖于经验观察而不是任何保证.

但是你在使用什么版本的SQL Server?如果SQL2005 +你可以用row_numberCTE 做一些事情(你可以更新CTE)

With cte As
(
SELECT id,Number,
ROW_NUMBER() OVER (ORDER BY id DESC) AS RN
FROM Test
)
UPDATE cte SET Number=RN
Run Code Online (Sandbox Code Playgroud)

  • 啊.你让我在那里!;)我在2005年才进入SqlServer世界,那里的CTE闪亮而且新颖.我一直认为row_number已经存在了一段时间. (2认同)

Mit*_*eat 17

您不能将ORDER BY用作UPDATE语句的一部分(您可以使用作为更新一部分的子选择).

UPDATE Test 
SET Number = rowNumber 
FROM Test
INNER JOIN 
(SELECT ID, row_number() OVER (ORDER BY ID DESC) as rowNumber
FROM Test) drRowNumbers ON drRowNumbers.ID = Test.ID
Run Code Online (Sandbox Code Playgroud)


Lie*_*ers 5

编辑

以下解决方案可能会涉及此处提到的聚集索引问题。感谢马丁指出这一点。

答案一直在教育那些不了解SQL Server所有副作用或来龙去脉的人(像我一样)。


在您的链接中扩展Quassnoi给出的答案,进行以下工作

DECLARE @Test TABLE (Number INTEGER, AText VARCHAR(2), ID INTEGER)
DECLARE @Number INT

INSERT INTO @Test VALUES (1, 'A', 1)
INSERT INTO @Test VALUES (2, 'B', 2)
INSERT INTO @Test VALUES (1, 'E', 5)
INSERT INTO @Test VALUES (3, 'C', 3)
INSERT INTO @Test VALUES (2, 'D', 4)

SET @Number = 0
Run Code Online (Sandbox Code Playgroud)
;WITH q AS (
    SELECT  TOP 1000000 *
    FROM    @Test
    ORDER BY
            ID
)            
UPDATE  q
SET     @Number = Number = @Number + 1
Run Code Online (Sandbox Code Playgroud)

  • 如果 id 是聚集索引,这可能会起作用,但不能保证起作用。请参阅此处的讨论http://weblogs.sqlteam.com/mladenp/archive/2009/07/28/SQL-Server-2005-Fast-Running-Totals.aspx (2认同)