137

増分番号で列 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

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

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

4

11 に答える 11

224

もう1つのオプション

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
于 2012-11-30T21:48:35.380 に答える
88
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/

于 2014-02-04T04:43:49.707 に答える
54
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
于 2012-11-30T16:28:57.537 に答える
22

2 回目の試行は主に、CTE に基になるテーブルと同じ名前を付け、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
于 2012-11-30T22:39:16.960 に答える
20

これは、WHERE句を追加した@Aleksandr Fedorenkoの回答の修正版です。

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 by を使用した私のクエリ

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
于 2016-12-28T07:52:21.920 に答える
2

私の場合、新しい列を追加し、テーブル全体の equivilat レコード番号で更新したかった

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,... の数字がありました

于 2021-04-25T06:18:30.840 に答える
0

複数のパーツをシーケンス番号に関連付けることができるパーツの最初のオカレンスで一時テーブルを更新します。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
于 2021-06-22T21:46:19.887 に答える