使用 row_number()进行 SQL 更新

我想用一个增量数字更新我的列 CODE _ DEST。我有:

CODE_DEST   RS_NOM
null        qsdf
null        sdfqsdfqsdf
null        qsdfqsdf

我想把它更新为:

CODE_DEST   RS_NOM
1           qsdf
2           sdfqsdfqsdf
3           qsdfqsdf

我试过这个代码:

UPDATE DESTINATAIRE_TEMP
SET CODE_DEST = TheId
FROM (SELECT  Row_Number()   OVER (ORDER BY [RS_NOM]) AS TheId FROM DESTINATAIRE_TEMP)

这不工作,因为 )

我也试过:

WITH DESTINATAIRE_TEMP AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY [RS_NOM] DESC) AS RN
FROM DESTINATAIRE_TEMP
)
UPDATE DESTINATAIRE_TEMP SET CODE_DEST=RN

但由于工会的存在,这种做法也不起作用。

如何使用 SQLServer2008R2中的 ROW_NUMBER()函数更新列?

258483 次浏览
With UpdateData  As
(
SELECT RS_NOM,
ROW_NUMBER() OVER (ORDER BY [RS_NOM] DESC) AS RN
FROM DESTINATAIRE_TEMP
)
UPDATE DESTINATAIRE_TEMP SET CODE_DEST = RN
FROM DESTINATAIRE_TEMP
INNER JOIN UpdateData ON DESTINATAIRE_TEMP.RS_NOM = UpdateData.RS_NOM

还有一个选择

UPDATE x
SET x.CODE_DEST = x.New_CODE_DEST
FROM (
SELECT CODE_DEST, ROW_NUMBER() OVER (ORDER BY [RS_NOM]) AS New_CODE_DEST
FROM DESTINATAIRE_TEMP
) x

第二次尝试失败的主要原因是,您将 CTE 命名为与基础表相同的 CTE,并使 CTE 看起来像是 递归性慢性创伤性脑病,因为它实际上引用了自己。递归性慢性创伤性脑病必须具有特定的结构,这需要使用 UNION ALL集合运算符。

相反,您可以给 CTE 一个不同的名称,并将目标列添加到其中:

With SomeName As
(
SELECT
CODE_DEST,
ROW_NUMBER() OVER (ORDER BY [RS_NOM] DESC) AS RN
FROM DESTINATAIRE_TEMP
)
UPDATE SomeName SET CODE_DEST=RN

更新游标的简单方法

UPDATE Cursor
SET Cursor.CODE = Cursor.New_CODE
FROM (
SELECT CODE, ROW_NUMBER() OVER (ORDER BY [CODE]) AS New_CODE
FROM Table Where CODE BETWEEN 1000 AND 1999
) Cursor
DECLARE @id INT
SET @id = 0
UPDATE DESTINATAIRE_TEMP
SET @id = CODE_DEST = @id + 1
GO

试试这个

Http://www.mssqltips.com/sqlservertip/1467/populate-a-sql-server-column-with-a-sequential-number-not-using-an-identity/

这是@Aleksandr Fedorenko 的答案的修改版本,添加了 WHERE 子句:

UPDATE x
SET x.CODE_DEST = x.New_CODE_DEST
FROM (
SELECT CODE_DEST, ROW_NUMBER() OVER (ORDER BY [RS_NOM]) AS New_CODE_DEST
FROM DESTINATAIRE_TEMP
) x
WHERE x.CODE_DEST <> x.New_CODE_DEST AND x.CODE_DEST IS NOT NULL

通过添加 WHERE 子句,我发现后续更新的性能大大提高了。Sql Server 似乎会更新该行,即使该值已经存在,而且这样做需要时间,因此添加 where 子句只会跳过值没有更改的行。我不得不说,我很惊讶它能如此迅速地运行我的查询。

免责声明: 我不是数据库专家,我使用 PARTITION BY 作为我的子句,所以这个查询的结果可能不完全相同。对我来说,这一栏是客户的付费订单,所以价值一般不会改变,一旦设置。

还要确保有索引,特别是如果 SELECT 语句上有 WHERE 子句。过滤后的索引对我很有用,因为我是根据支付状态进行过滤的。


使用 PARTITION 的查询

UPDATE  UpdateTarget
SET     PaidOrderIndex = New_PaidOrderIndex
FROM
(
SELECT  PaidOrderIndex, SimpleMembershipUserName, ROW_NUMBER() OVER(PARTITION BY SimpleMembershipUserName ORDER BY OrderId) AS New_PaidOrderIndex
FROM    [Order]
WHERE   PaymentStatusTypeId in (2,3,6) and SimpleMembershipUserName is not null
) AS UpdateTarget


WHERE UpdateTarget.PaidOrderIndex <> UpdateTarget.New_PaidOrderIndex AND UpdateTarget.PaidOrderIndex IS NOT NULL


-- test to 'break' some of the rows, and then run the UPDATE again
update [order] set PaidOrderIndex = 2 where PaidOrderIndex=3

如果该列不可为空,则不需要“ IS NOT NULL”部分。


当我说性能提高很大时,我的意思是当更新少量行时,它基本上是即时的。使用正确的索引,我能够实现一个与“内部”查询本身所花费的时间相同的更新:

  SELECT  PaidOrderIndex, SimpleMembershipUserName, ROW_NUMBER() OVER(PARTITION BY SimpleMembershipUserName ORDER BY OrderId) AS New_PaidOrderIndex
FROM    [Order]
WHERE   PaymentStatusTypeId in (2,3,6) and SimpleMembershipUserName is not null

我这么做是为了我的处境

WITH myUpdate (id, myRowNumber )
AS
(
SELECT id, ROW_NUMBER() over (order by ID) As myRowNumber
FROM AspNetUsers
WHERE  UserType='Customer'
)


update AspNetUsers set EmployeeCode = FORMAT(myRowNumber,'00000#')
FROM myUpdate
left join AspNetUsers u on u.Id=myUpdate.id

如果表没有关系,只需复制所有新表中的行号,删除旧表,并用旧表重命名新表。

Select   RowNum = ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) , * INTO cdm.dbo.SALES2018 from
(
select * from SALE2018) as SalesSource

在我的示例中,我添加了一个新列,并希望用整个表的 equevilat 记录编号来更新它

id  name       new_column (ORDER_NUM)
1   Ali        null
2   Ahmad      null
3   Mohammad   null
4   Nour       null
5   Hasan      null
6   Omar       null

我编写这个查询是为了用行号填充新列

UPDATE My_Table
SET My_Table.ORDER_NUM  = SubQuery.rowNumber
FROM (
SELECT id ,ROW_NUMBER() OVER (ORDER BY [id]) AS rowNumber
FROM My_Table
) SubQuery
INNER JOIN My_Table ON
SubQuery.id = My_Table.id

在执行这个查询之后,我的新列中出现了1、2、3、 ... 数字

我更新了一个临时表,其中首次出现了多个部分可以与序列号相关联的部分。RowId = 1返回使用部件和序列号连接 tmp 表和数据的第一个事件。

update #Tmp
set
#Tmp.Amount=@Amount
from
(SELECT Part, Row_Number()   OVER (ORDER BY [Part]) AS RowId FROM #Tmp
where Sequence_Num=@Sequence_Num
)data
where data.Part=#Tmp.Part
and data.RowId=1
and #Tmp.Sequence_Num=@Sequence_Num

我没有一个正在运行的 ID 来做“ Basheer AL-MOMANI”的建议。 我做了这样的事情: (加入我的表自己,只是为了得到行号)

update T1 set inID = T2.RN
from (select *, ROW_NUMBER() over (order by ID) RN from MyTable) T1
inner join (select *, ROW_NUMBER() over (order by ID) RN from MyTable) T2 on T2.RN = T1.RN