将标识列添加到现有表作为主键并更改顺序

bob*_*bbo 4 sql sql-server

我有一张表,里面有超过700万条记录.该表没有主键.我想添加一个新的标识列并将其设置为主键.我尝试使用SSMS添加列,然后将其设置为主键.我把这个新列称为Id.

这几乎可以工作,但我想将表的默认顺序更改为基于另一列,例如日期时间列按降序排列.这可能吗?也许我需要使用临时表和ROW_NUMBER()函数.

但是,我不是很擅长SQL.有人可以帮忙吗?

我还需要一个回滚脚本,以便我可以回到原始表.

Nen*_*vic 12

这是另一个想法:

步骤1 - 在"日期时间列按降序排列"上创建临时聚簇索引

CREATE CLUSTERED INDEX ix_YourTableTEMP ON YourTable (DateTimeColumn DESC)
Run Code Online (Sandbox Code Playgroud)

第2步 - 添加标识列.现在ID 应该按照之前创建的索引的顺序排列 - 虽然我不认为这有100%的保证.

ALTER TABLE YourTable ADD IdColumn INT IDENTITY(1,1)
Run Code Online (Sandbox Code Playgroud)

Step3 - 删除临时索引

DROP INDEX  ix_YourTableTEMP ON YourTable 
Run Code Online (Sandbox Code Playgroud)

步骤4 - 在新列上创建新的群集PK

ALTER TABLE YourTable 
ADD CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED (IdColumn)
Run Code Online (Sandbox Code Playgroud)


Gar*_*thD 2

马丁·史密斯给出的链接可能是最好的答案,但这里有一个替代方案

-- 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;
Run Code Online (Sandbox Code Playgroud)

回滚:

ALTER TABLE T DROP COLUMN ID;
Run Code Online (Sandbox Code Playgroud)

编辑

有人指出,SELECT ID = IDENTITY(INT, 1, 1).. INTO.. FROM .. ORDER BY ...不保证插入的顺序。因此,故障安全选项似乎是使用CREATE TABLE语法创建克隆表并添加IDENTITY列:

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 ...;
Run Code Online (Sandbox Code Playgroud)

然后继续执行 Drop 并重命名,如上所述。我找不到任何文档说明此方法对于订购插入件不可靠,如果证明仍然不可靠,您可以使用:

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;
Run Code Online (Sandbox Code Playgroud)

然后在插入后重新播种 T_CLone。