Обновляемый CTE, использующий ROW_NUMBER
и оконный MAX
для получения новых значений идентификатора, может показаться наиболее простым решением:
CREATE TABLE dbo.YourTable (ID int,
[timestamp] datetime2(3)); --This is a bad name for a column, as timestamp is a synonym for rowversion
INSERT INTO dbo.YourTable (ID, [timestamp])
VALUES (101,'2020-01-01T11:02:14.235'),
(102,'2020-01-01T12:05:04.123'),
(103,'2020-01-01T13:20:50.457'),
(104,'2020-01-01T14:20:53.447'),
(105,'2020-01-01T15:25:25.125'),
( 0,'2020-01-01T16:25:14.447'),
( 0,'2020-01-02T20:26:01.147'),
( 0,'2020-01-01T17:18:39.987'),
( 0,'2020-01-01T19:14:14.014'),
( 0,'2020-01-01T18:10:10.000');
GO
WITH CTE AS(
SELECT ID,
ROW_NUMBER() OVER (PARTITION BY CASE ID WHEN 0 THEN 0 END ORDER BY [timestamp]) + MAX(ID) OVER () AS NewID
FROM dbo.YourTable)
UPDATE CTE
SET ID = NewID
WHERE ID = 0;
GO
SELECT *
FROM dbo.YourTable;
GO
Примечание. Как число, которое вы если слева от ваших данных нет столбца, то «порядок» ваших данных будет потерян; но тогда он не был сохранен в первую очередь, поскольку only способ гарантировать порядок данных в СУБД - это ORDER BY
, который создает уникальный «набор» для каждой строки.