SQL Server:使用ORDER BY更新表

我想知道在更新表时是否有一种方法可以使用order by子句。 我正在更新一个表并设置一个连续的数字,这就是为什么更新的顺序是重要的。 使用下面的sql语句,我能够解决它而不使用游标:

DECLARE @Number INT = 0 UPDATE Test SET @Number = Number = @Number +1 

现在我想要做的是按照这样的顺序:

  DECLARE @Number INT = 0 UPDATE Test SET @Number = Number = @Number +1 ORDER BY Test.Id DESC 

我读过: 如何通过使用MS SQL更新和订购这个问题的解决scheme不解决sorting问题 – 他们只是过滤应用更新的项目。

保重,马丁

没有。

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

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

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

您不能使用ORDER BY作为UPDATE语句的一部分(您可以在作为更新的一部分的子select中使用)。

 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 

编辑

以下解决scheme可能会遇到与此处提到的聚集索引有关的问题。 感谢马丁指出了这一点。

答案是不断教育那些不知道SQL Server的所有副作用或者来龙去脉的人(比如我)。


在你的链接上扩大Quassnoi的答案gaven,下面的作品

 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 

 ;WITH q AS ( SELECT TOP 1000000 * FROM @Test ORDER BY ID ) UPDATE q SET @Number = Number = @Number + 1 

row_number()函数将是解决此问题的最佳方法。

 UPDATE T SET T.Number = R.rowNum FROM Test T JOIN ( SELECT T2.id,row_number() over (order by T2.Id desc) rowNum from Test T2 ) R on T.id=R.id 

我遇到了同样的问题,并能够以非常强大的方式解决它,使无限的sorting可能性。

我使用(保存)2个sorting命令创build了一个视图(*关于如何做到这一点的解释)。

之后,我只是将更新查询应用到创build的视图,它运作良好。

以下是我在视图中使用的两个查询:

第一个查询:

 Update MyView Set SortID=0 

第二个查询:

 DECLARE @sortID int SET @sortID = 0 UPDATE MyView SET @sortID = sortID = @sortID + 1 

*为了能够在视图上保存sorting,我把TOP放到SELECT语句中。 这种非常有用的解决方法允许在View打开时创buildView时,将查看结果按设置返回sorting。 在我看来,它看起来像:

(注意:如果使用大型表,使用此解决方法会在服务器上造成很大的负载,因此build议在处理大型表时尽可能在视图中包含尽可能less的字段)

 SELECT TOP (600000) dbo.Items.ID, dbo.Items.Code, dbo.Items.SortID, dbo.Supplier.Date, dbo.Supplier.Code AS Expr1 FROM dbo.Items INNER JOIN dbo.Supplier ON dbo.Items.SupplierCode = dbo.Supplier.Code ORDER BY dbo.Supplier.Date, dbo.Items.ID DESC 

运行:Windows Server 2003上的SQL Server 2005

其他关键字:如何使用升序或降序数字更新SQL列 – 数值如何在SQL更新语句中设置顺序/如何保存顺序在SQL视图/增量SQL更新/自动自动增量SQL更新/创buildSQL字段升序数字

根据SQL IN()子句中的值的顺序sorting进行更新

解:

 DECLARE @counter int SET @counter = 0 ;WITH q AS ( select * from Products WHERE ID in (SELECT TOP (10) ID FROM Products WHERE ID IN( 3,2,1) ORDER BY ID DESC) ) update q set Display= @counter, @counter = @counter + 1 

这根据降序3,2,1更新

希望有助于某人。

我有一个类似的问题,并使用ROW_NUMBER()结合OVER关键字解决它。 这个任务是在一个基于原始的CreatedDate的简单表格中追溯填充一个新的TicketNo(整数)字段,并按照ModuleId进行分组 – 以便票号在每个Module组中从1开始,并按date递增。 该表已经有一个TicketID主键(一个GUID)。

这里是SQL:

 UPDATE Tickets SET TicketNo=T2.RowNo FROM Tickets INNER JOIN (select TicketID, TicketNo, ROW_NUMBER() OVER (PARTITION BY ModuleId ORDER BY DateCreated) AS RowNo from Tickets) AS T2 ON T2.TicketID = Tickets.TicketID 

做了一个治疗!

我已经在MYSQL中testing了下面的代码来更新最新的logging。这就是为什么我首先使用了命令。它将更新最新logging的状态列

  UPDATE DBTest.logTable SET status='Test' ORDER BY ID DESC limit 1 ;