列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()
関数を使用して列を更新するにはどうすればよいですか?
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
DECLARE @id INT
SET @id = 0
UPDATE DESTINATAIRE_TEMP
SET @id = CODE_DEST = @id + 1
GO
これを試して
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
これは、@ 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
テーブルにリレーションがない場合、新しいテーブルのすべてを行番号でコピーし、古いものを削除して、新しいものを古いものに変更します。
RowNum = ROW_NUMBER()OVER(ORDER BY(SELECT NULL))を選択し、* SalesSourceとしてcdm.dbo.SALES2018から(select *からSALE2018)
私は自分の状況のためにこれを行い、働いた
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
カーソルを更新するシンプルで簡単な方法
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