我需要创建一个包含增量ID的表,但是我希望这些ID根据另一列自动进行细分。这是我想要的:
CREATE TABLE dbo.MyTable ( myKey INT IDENTITY PRIMARY KEY, category INT, incrementalId INT ); INSERT INTO dbo.MyTable (category) VALUES (100); INSERT INTO dbo.MyTable (category) VALUES (200); INSERT INTO dbo.MyTable (category) VALUES (100); INSERT INTO dbo.MyTable (category) VALUES (100); INSERT INTO dbo.MyTable (category) VALUES (100); INSERT INTO dbo.MyTable (category) VALUES (200); SELECT * FROM dbo.MyTable;
我想要显示类似以下内容:
myKey category incrementalId ----------- ----------- ------------- 1 100 1 2 200 1 3 100 2 4 100 3 5 100 4 6 200 2
意思是我希望incrementalId每个类别自动递增,并为插入的任何新类别从1重新开始。我希望在表中的任何插入处自己完成此操作(我不想在插入此表时记得这样做)。
incrementalId
我认为这可以通过窗口函数或触发器来完成,但我不知道如何做到。
编辑:
我希望数据能够持久保存,以避免在发生数据删除时对增量ID进行移位。另外,理想情况下,在删除行的情况下,不会重新赋予相同的ID(与序列或IDENTITY的工作方式相同)
任何的想法 ?
CREATE TABLE dbo.MyTable ( myKey INT IDENTITY PRIMARY KEY, category INT, incrementalId INT ); GO create table dbo.nextCategoryID ( category int, nextidvalue int, constraint PK_nextCategoryID primary key clustered( category, nextidvalue ) ); GO create trigger numberByCategory on dbo.MyTable after insert as -- Automatically add any net new category insert into dbo.nextCategoryID ( category, nextidvalue ) select distinct category, 1 as nextidvalue from inserted where not exists ( select * from dbo.nextCategoryID s where s.category = inserted.category ); -- Number the new rows in each incoming category with numberedrows as ( select i.myKey, i.category, n.nextidvalue - 1 + row_number() over ( partition by i.category order by i.category ) as incrementalId from inserted i join dbo.nextCategoryID n on i.category = n.category ) update m set incrementalId = n.incrementalId from dbo.MyTable m join inserted i on m.myKey = i.myKey join numberedrows n on n.myKey = i.myKey; update dbo.nextCategoryID set nextidvalue = 1 + ( select max( m.incrementalId ) from inserted i join dbo.MyTable m on i.myKey = m.myKey where i.category = nextCategoryID.category ) where exists ( select * from inserted i where i.category = nextCategoryID.category ); GO -- Test data INSERT INTO dbo.MyTable (category) VALUES (100); INSERT INTO dbo.MyTable (category) VALUES (200); INSERT INTO dbo.MyTable (category) VALUES (100); INSERT INTO dbo.MyTable (category) VALUES (100); INSERT INTO dbo.MyTable (category) VALUES (100); INSERT INTO dbo.MyTable (category) VALUES (200); insert into dbo.MyTable (category) values ( 200 ), ( 200 ), ( 100 ), ( 300 ), ( 400 ), ( 400 ) SELECT * FROM dbo.MyTable;