更改表以根据Order By添加Identity列

时间:2016-11-24 23:24:32

标签: sql sql-server tsql

我有这张桌子

------------------------------------
| **Id**  |**Name**  | **Created** | 
------------------------------------
| Guid1   | John Doe |  2016-01-01 |
------------------------------------
| Guid2   | Mary Jane|  2015-01-01 |
------------------------------------

列ID是PK和聚簇索引,所以我想添加一个标识列:

ALTER TABLE [Person]
ADD
IdentityCol INT IDENTITY(1,1) NOT NULL

问题是,每当我尝试这样做时,它会根据表的默认顺序添加IdentityCol的值,我想这是由列Id

定义的。

-------------------------------------------------
| **Id**  |**Name**  | **Created** | IdentityCol|
-------------------------------------------------
| Guid1   | John Doe |  2016-01-01 |    1       |
-------------------------------------------------
| Guid2   | Mary Jane|  2015-01-01 |    2       |
-------------------------------------------------

购买我想要的是按创建列

创建值顺序
-------------------------------------------------
| **Id**  |**Name**  | **Created** | IdentityCol|
-------------------------------------------------
| Guid1   | John Doe |  2016-01-01 |    2       |
-------------------------------------------------
| Guid2   | Mary Jane|  2015-01-01 |    1       |
-------------------------------------------------

有没有办法在ALTER句子中指定Order By?

4 个答案:

答案 0 :(得分:5)

使用行号:

*(&(arr[i]) + 1)

然后您可以通过以下方式将UPDATE Person p SET IdentityCol = (SELECT ROW_NUMBER() over (ORDER BY Created) AS rn FROM Person t WHERE p.Id = t.Id) 设置为正式的标识列:

IdentityCol

答案 1 :(得分:2)

您必须创建一个具有相同结构+标识列的新表。通过订购

将旧数据插入其中
Insert into ...
Select ...
Order by ...

否则你必须考虑添加一个列(不是标识)。按照您想要的顺序填写自动数字,如@Tim回答。然后将其设置为标识

答案 2 :(得分:1)

我不知道这是否是解决我问题的正确方法,但我最后结束了这样的事情:

首先,我删除SQL为PK(列ID)创建的索引。

ALTER TABLE [Person] DROP CONSTRAINT PK__PersonId

只有当您没有任何与列相关的表时,这才有效,并且同时删除了人员表的PK。

其次,我在Created列上创建了一个时间聚簇索引:

CREATE CLUSTERED INDEX IX_CreatedTemp ON [Person] (Created ASC)

现在,SQL基于Created列对表进行排序,现在我可以添加我的Identity列。

ALTER TABLE [Person]
    ADD IdentityCol INT UNIQUE IDENTITY(1,1) NOT NULL

添加列时,SQL会根据默认顺序自动填充值,该默认顺序由索引IX_CreatedTemp确定。

所以结果就像我预期的那样

**人**

-------------------------------------------------
| **Id**  |**Name**  | **Created** | IdentityCol|
-------------------------------------------------
| Guid1   | John Doe |  2016-01-01 |    2       |
-------------------------------------------------
| Guid2   | Mary Jane|  2015-01-01 |    1       |
-------------------------------------------------

现在是时候将列ID作为PK返回。首先,我删除我的临时索引:

DROP INDEX  IX_CreatedTemp ON [Person]

现在添加PK:

ALTER TABLE [Person] 
    ADD CONSTRAINT PK_Person PRIMARY KEY NONCLUSTERED (Id)

最后,我添加了一个基于我的新IdentityCol的新索引,以使我的表更快

CREATE UNIQUE CLUSTERED INDEX IX_IdentityCol ON [Person] (IdentityCol ASC)

一切都很好。

答案 3 :(得分:0)

您无法更新IDENTITY cloumn,删除并插入

select Id,Name,Created into #temptable from [Person]
TRUNCATE TABLE [Person]
ALTER TABLE [Person] ADD [IdentityCol] INT IDENTITY(1,1) NOT NULL

INSERT INTO [Person](Id,Name,Created)
select Id,Name,Created from #temptable order by Created