The Link Martin Smith has given is probably the best answer, but here is an alternative:
-- CREATE TABLE WITH SOME DATA IN
CREATE TABLE T (X INT);
INSERT T VALUES (1), (2), (3);
-- CREATE A CLONE OF THIS TABLE, ADDING AN IDENTITY COLUMN
-- USING ORDER BY TO AFFECT THE ORDER OF THE INSERT
SELECT ID = IDENTITY(INT, 1, 1),
T.*
INTO T_Clone
FROM T
ORDER BY X DESC;
-- DROP ORIGINAL TABLE
DROP TABLE T;
-- RENAME CLONE TABLE TO ORIGINAL TABLE NAME
EXECUTE SP_RENAME 'dbo.T_Clone', 'T', 'OBJECT';
-- SELECT FROM TABLE TO CHECK RESULTS
SELECT *
FROM T;
To rollback:
ALTER TABLE T DROP COLUMN ID;
EDIT
It has been pointed out that SELECT ID = IDENTITY(INT, 1, 1).. INTO.. FROM .. ORDER BY ...
does not guarantee the order of the insert. So it would appear that the fail safe option is to create your clone table using CREATE TABLE
syntax and adding the IDENTITY
column:
CREATE TABLE T_Clone
( ID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY,
<your columns>
);
INSERT T_Clone (<your columns>)
SELECT <your columns>
FROM T
ORDER BY ...;
Then carry on with the Drop and rename as above. I can find no documentation to say this method is not reliable for ordering the insert, if it proves to still not be reliable you could use:
SET IDENTITY_INSERT T_Clone ON;
INSERT T_Clone (ID, <your columns>)
SELECT ROW_NUMBER() OVER(ORDER BY ...),
<your columns>
FROM T;
SET IDENTITY_INSERT T_Clone OFF;
Then reseed T_CLone after the insert.