Sql Alter table根据Order By添加标识列
我有这张桌子 人Sql Alter table根据Order By添加标识列,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有这张桌子 人 ------------------------------------ | **Id** |**Name** | **Created** | ------------------------------------ | Guid1 | John Doe | 2016-01-01 | ------------------------------------ | Guid2 | Mary Jane| 2015-01-01 | ------------------
------------------------------------
| **Id** |**Name** | **Created** |
------------------------------------
| Guid1 | John Doe | 2016-01-01 |
------------------------------------
| Guid2 | Mary Jane| 2015-01-01 |
------------------------------------
-------------------------------------------------
| **Id** |**Name** | **Created** | IdentityCol|
-------------------------------------------------
| Guid1 | John Doe | 2016-01-01 | 1 |
-------------------------------------------------
| Guid2 | Mary Jane| 2015-01-01 | 2 |
-------------------------------------------------
Column Id是PK和聚集索引,因此我想添加一个标识列:
ALTER TABLE [Person]
ADD
IdentityCol INT IDENTITY(1,1) NOT NULL
问题是每次我尝试这样做时,它都会根据表的默认顺序添加IdentityCol的值,我认为这是由列Id定义的
人
------------------------------------
| **Id** |**Name** | **Created** |
------------------------------------
| Guid1 | John Doe | 2016-01-01 |
------------------------------------
| Guid2 | Mary Jane| 2015-01-01 |
------------------------------------
-------------------------------------------------
| **Id** |**Name** | **Created** | IdentityCol|
-------------------------------------------------
| Guid1 | John Doe | 2016-01-01 | 1 |
-------------------------------------------------
| Guid2 | Mary Jane| 2015-01-01 | 2 |
-------------------------------------------------
购买我想要的是创建值order by Created列
-------------------------------------------------
| **Id** |**Name** | **Created** | IdentityCol|
-------------------------------------------------
| Guid1 | John Doe | 2016-01-01 | 2 |
-------------------------------------------------
| Guid2 | Mary Jane| 2015-01-01 | 1 |
-------------------------------------------------
有没有办法在ALTER语句中指定顺序?使用行号:
UPDATE Person p
SET IdentityCol = (SELECT ROW_NUMBER() over (ORDER BY Created) AS rn
FROM Person t WHERE p.Id = t.Id)
然后,您可以通过以下方式将IdentityCol
设置为正式标识列:
SET IDENTITY_INSERT database.schema.Person ON
您必须创建一个具有相同结构+标识列的新表。按顺序将旧数据插入其中
Insert into ...
Select ...
Order by ...
否则,您必须考虑添加列(而不是标识)。按照您想要的顺序,如@Tim answer,填写自动编号。然后将其设置为identity您不能更新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
我不知道这是否是解决我问题的正确方法,但我以这样的方式结束: 首先,我删除SQL为PK创建的索引(列Id) 只有当您没有任何与此列Id相关的表,并且同时删除了Person表的PK时,此操作才有效 其次,我在创建的列上创建一个临时聚集索引:
CREATE CLUSTERED INDEX IX_CreatedTemp ON [Person] (Created ASC)
现在SQL根据创建的列对表进行排序,这样现在我就可以添加标识列了
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)
一切正常。可能使用
设置标识\u插入数据库.schema.Person上的?作业完成后,将其设置为OFF
。表格没有顺序。实现具有顺序,但从表中选择并不保证重新选择该顺序。因此,这似乎只起作用。窗口函数允许您选择一个新的列,该列按照TimBiegeleisen的答案中的顺序保存行号。