はい、私はその結果をよく知っています。しかし、私はそれらを並べ替えたいだけです。1から最後まで。
単一のクエリを使用してキーを並べ替えるにはどうすればよいですか?
クラスタ化された主キーインデックスです
のように並べ替え
First record Id 1
second record Id 2
主キーはIntです
はい、私はその結果をよく知っています。しかし、私はそれらを並べ替えたいだけです。1から最後まで。
単一のクエリを使用してキーを並べ替えるにはどうすればよいですか?
クラスタ化された主キーインデックスです
のように並べ替え
First record Id 1
second record Id 2
主キーはIntです
USE Test
go
if(object_id('IdentityTest') Is not null)
drop table IdentityTest
create table IdentityTest
(
Id int identity not null,
Name varchar(5),
constraint pk primary key (Id)
)
set identity_insert dbo.IdentityTest ON
insert into dbo.IdentityTest (Id,Name) Values(23,'A'),(26,'B'),(34,'C'),(35,'D'),(40,'E')
set identity_insert dbo.IdentityTest OFF
select * from IdentityTest
------------------1. Drop PK constraint ------------------------------------
ALTER TABLE [dbo].[IdentityTest] DROP CONSTRAINT [pk]
GO
------------------2. Drop Identity column -----------------------------------
ALTER table dbo.IdentityTest
drop column Id
------------------3. Re-create Identity Column -----------------------------------
ALTER table dbo.IdentityTest
add Id int identity(1,1)
-------------------4. Re-Create PK-----------------------
ALTER TABLE [dbo].[IdentityTest] ADD CONSTRAINT [pk] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
--------------------------------------------------------------
insert into dbo.IdentityTest (Name) Values('F')
select * from IdentityTest
IDENTITY
SET IDENTITY_INSERT
オプションに関係なく、列は更新できません。
プロパティを除いて、元のテーブルと同じ定義でシャドウテーブルを作成できますIDENTITY
。それに切り替えて(これは、テーブルの定義に影響を与えるだけの行の移動を伴わないメタデータのみの変更です)、行を更新して元に戻します。
ギャップがある状況からギャップがない状況への完全な実例を以下に示します(簡潔にするために、エラー処理とトランザクションは以下で省略されています)。
/*Your original table*/
CREATE TABLE YourTable
(
Id INT IDENTITY PRIMARY KEY,
OtherColumns CHAR(100) NULL
)
/*Some dummy data*/
INSERT INTO YourTable (OtherColumns) VALUES ('A'),('B'),('C')
/*Delete a row leaving a gap*/
DELETE FROM YourTable WHERE Id =2
/*Verify there is a gap*/
SELECT *
FROM YourTable
/*Create table with same definition as original but no `IDENTITY`*/
CREATE TABLE ShadowTable
(
Id INT PRIMARY KEY,
OtherColumns CHAR(100)
)
/*1st metadata switch*/
ALTER TABLE YourTable SWITCH TO ShadowTable;
/*Do the update*/
WITH CTE AS
(
SELECT *,
ROW_NUMBER() OVER (ORDER BY Id) AS RN
FROM ShadowTable
)
UPDATE CTE SET Id = RN
/*Metadata switch back to restore IDENTITY property*/
ALTER TABLE ShadowTable SWITCH TO YourTable;
/*Remove unneeded table*/
DROP TABLE ShadowTable;
/*No Gaps*/
SELECT *
FROM YourTable
単一のクエリでこれを行う方法はないと思います。最善の策は、データを新しいテーブルにコピーし、元のテーブルを削除して再作成し(または、データを削除してIDを再シードし)、以前のIDを順序として使用して、元の順序でデータを再挿入することです(ただし、再挿入はしません)。それ)。
CREATE TABLE Table1_Stg (bla bla bla)
INSERT INTO Table1_Stg (Column2, Column3,...) SELECT Column2, Column3,... FROM Table1 ORDER BY Id
ここで、Id列はSELECT列リストから除外されています。
または、次のことができます。
SELECT * INTO Table1_Stg FROM Table1 ORDER BY Id
DROP Table1
sp_rename Table1_stg Table1
私はこれをメモリから行っているので、sp_renameの使用法を調べてください。
お役に立てれば。
編集:Table1にすべてのインデックスと制約がある場合は、スクリプトを保存してください。
EDIT2:テーブルを作成してテーブルに挿入する2番目の方法を追加しました。
UPDATE tbl SET id = (SELECT COUNT(*) FROM tbl t WHERE t.id <= tbl.id);
この最後の声明は天才です。最初にテーブルデザインから主キーを削除し、デザインオプションで[ID仕様]が[いいえ]に設定されていることを確認する必要がありました。クエリを実行したら、これらのオプションを元に戻します。