web-dev-qa-db-ja.com

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

しかし、これも組合のために機能しません。

SQL Server 2008 R2でROW_NUMBER()関数を使用して列を更新するにはどうすればよいですか?

90
user609511
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
39
user609511

もう一つのオプション

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
156
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/

55
vasin1987

2回目の試行は、主にCTEを基になるテーブルと同じ名前にし、CTEを再帰CTEのように見せたために失敗しました。自体。 再帰CTE には、UNION ALL set演算子の使用を必要とする特定の構造が必要です。

代わりに、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
15
Andriy M

これは、@ 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句を追加すると、値が変更されていない行をスキップします。クエリの実行速度に驚いたと言わざるを得ません。

免責事項:私はDBの専門家ではありません。また、句に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

列がNULL可能でない場合、「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
13
Simon_Weaver

テーブルにリレーションがない場合、新しいテーブルのすべてを行番号でコピーし、古いものを削除して、新しいものを古いものに変更します。

RowNum = ROW_NUMBER()OVER(ORDER BY(SELECT NULL))を選択し、* SalesSourceとしてcdm.dbo.SALES2018から(select *からSALE2018)

1
Ubaid Mughal

私は自分の状況のた​​めにこれを行い、働いた

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
1
Arun Prasad E S

カーソルを更新するシンプルで簡単な方法

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
1
Rahim Surani