Je souhaite mettre à jour ma colonne CODE_DEST avec un numéro incrémentiel. J'ai:
CODE_DEST RS_NOM
null qsdf
null sdfqsdfqsdf
null qsdfqsdf
Je voudrais le mettre à jour pour être:
CODE_DEST RS_NOM
1 qsdf
2 sdfqsdfqsdf
3 qsdfqsdf
J'ai essayé ce code:
UPDATE DESTINATAIRE_TEMP
SET CODE_DEST = TheId
FROM (SELECT Row_Number() OVER (ORDER BY [RS_NOM]) AS TheId FROM DESTINATAIRE_TEMP)
Cela ne fonctionne pas à cause du )
J'ai aussi essayé:
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
Mais cela ne fonctionne pas non plus à cause de l'union.
Comment mettre à jour une colonne à l'aide de la fonction ROW_NUMBER()
dans SQL Server 2008 R2?
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
Une autre option
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
essaye ça
Votre deuxième tentative a échoué principalement parce que vous avez nommé le CTE identique à la table sous-jacente et lui avez donné l’impression qu’il s’agissait d’un CTE récursif , car il faisait essentiellement référence à lui-même. Un CTE récursif doit avoir une structure spécifique nécessitant l'utilisation de l'opérateur UNION ALL
set.
Au lieu de cela, vous auriez simplement pu donner un nom différent au CTE et y ajouter la colonne cible:
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
Ceci est une version modifiée de la réponse de @Aleksandr Fedorenko en ajoutant une clause 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
En ajoutant une clause WHERE, les performances ont été considérablement améliorées lors des mises à jour ultérieures. Sql Server semble mettre à jour la ligne même si la valeur existe déjà et que cela prend du temps. Par conséquent, l'ajout de la clause where permet d'éviter les lignes dont la valeur n'a pas changé. Je dois dire que j'ai été étonné de la rapidité avec laquelle ma requête pouvait être exécutée.
Clause de non-responsabilité: je ne suis pas un expert en bases de données et j'utilise PARTITION BY pour ma clause. Il est donc possible que les résultats ne soient pas identiques pour cette requête. Pour moi, la colonne en question est une commande payée par un client. Par conséquent, la valeur ne change généralement pas une fois définie.
Assurez-vous également que vous avez des index, en particulier si vous avez une clause WHERE sur l'instruction SELECT. Un index filtré fonctionnait très bien pour moi car je filtrais en fonction du statut des paiements.
Ma requête en utilisant PARTITION par
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
La partie 'IS NOT NULL' n'est pas obligatoire si la colonne n'est pas nullable.
Lorsque je dis que l’augmentation des performances était massive, je veux dire qu’elle était essentiellement instantanée lors de la mise à jour d’un petit nombre de lignes. Avec les bons index, j'ai pu réaliser une mise à jour prenant le même temps que la requête "interne":
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
Si la table n'a pas de relation, il suffit de copier la nouvelle table avec le numéro de ligne, de supprimer l'ancienne et de renommer la nouvelle avec l'ancienne.
Sélectionnez RowNum = ROW_NUMBER () OVER (ORDER BY (SELECT NULL)), * INTO cdm.dbo.SALES2018 parmi (sélectionnez * dans SALE2018) en tant que SalesSource.
Je l'ai fait pour ma situation et a travaillé
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
Moyen simple et facile de mettre à jour le curseur
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