我有一张表中有超过700万条记录。该表没有主键。我想添加一个新的标识列并将其设置为主键。我尝试使用SSMS添加列,然后将其设置为主键。我把这个新列称为Id。
这几乎可以工作,但我想将表的默认顺序更改为基于另一列,例如日期时间列按降序排列。这可能吗?也许我需要使用临时表和ROW_NUMBER()
函数。
但是,我不是很擅长SQL。有人可以帮忙吗?
我还需要一个回滚脚本,以便我可以回到原始表。
答案 0 :(得分:11)
这是另一个想法:
Step1 - 在“日期时间列按降序排列”中创建临时聚集索引
CREATE CLUSTERED INDEX ix_YourTableTEMP ON YourTable (DateTimeColumn DESC)
Step2 - 添加标识列。现在ID 应该按照之前创建的索引的顺序排列 - 尽管我认为没有100%的保证。
ALTER TABLE YourTable ADD IdColumn INT IDENTITY(1,1)
Step3 - 删除临时索引
DROP INDEX ix_YourTableTEMP ON YourTable
Step4 - 在新列上创建新的群集PK
ALTER TABLE YourTable
ADD CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED (IdColumn)
答案 1 :(得分:2)
{3}}马丁史密斯给出的可能是最好的答案,但这里有另一种选择:
-- 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;
要回滚:
ALTER TABLE T DROP COLUMN ID;
修改强>
有人指出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 ...;
然后继续使用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;
然后在插入后重新设置T_CLone。