sql-server - 有效地插入序列号 1-N 并重新编号重复项

标签 sql-server algorithm

我有一个主键是正整数的表:

CREATE TABLE T
(
    ID int PRIMARY KEY CHECK (ID > 0) -- not an IDENTITY column
    -- ... other irrelevant columns...
)

给定一个正整数 N,我想插入 ID 为 1–N(含)的 N 条记录。但是,如果具有特定 ID 的记录已经存在,我想插入下一个最高的未使用 ID。例如,N = 5:

If the table contains...    Then insert...
  (Nothing)                   1,2,3,4,5
  1,2,3                       4,5,6,7,8
  3,6,9,12                    1,2,4,5,7

这是一种简单的方法:

DECLARE @N int = 5 -- number of records to insert
DECLARE @ID int = 1 -- next candidate ID
WHILE @N > 0 -- repeat N times
BEGIN
    WHILE EXISTS(SELECT * FROM T WHERE ID = @ID) -- conflicting record?
        SET @ID = @ID + 1
    INSERT T VALUES (@ID)
    SET @ID = @ID + 1
    SET @N = @N - 1
END

但是如果 E 是现有记录的数量,那么在最坏的情况下,这段代码会执行 E + N SELECT 和 N 次 INSERT,效率很低。

有没有一种聪明的方法可以用少量的 SELECT 和一个 INSERT 来执行这个任务?

最佳答案

你可以使用理货表和 NOT IN 我想......

WITH
    E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
    E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
    E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
    cteTally(N) AS 
    (
        SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
    )
select N into #temp from cteTally



declare @table table (i int)
insert into @table
values
(3),
(6),
(9),
(12)


insert into @table
select top 5 N from #temp where N not in (select i from @table) order by N


select * from @table

drop table #temp

信用 @SeanLange用于强调理货表并最初向我展示

关于sql-server - 有效地插入序列号 1-N 并重新编号重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45147503/

相关文章:

sql-server - SQL Server 2005查询XML时,文档的多个标签在同一行

sql - 存储过程 EXEC 与 sp_executesql 的区别?

c++ - 使用对象名称识别容器中的对象?

arrays - 数组算法中的匹配

algorithm - 不一致(非传递)人类偏好的排序算法

sql-server - 将 CSV 从 Azure blob 加载到 Azure SQL 的 SSIS 步骤

sql-server - 微软 azure : Could not submit the request to create database 'Name'

sql - 在单个 SQL 查询中查找多个父级的所有子级

c# - 通过点集合中的所有其他点,两点之间的最短路线

algorithm - 计划一个和平的聚会