SQL-删除后将连续列重新编号为连续列

SQL-删除后将连续列重新编号为连续列,sql,Sql,我已经研究并意识到我有一个独特的情况 首先,由于我是一个新用户,我还不允许将图片发布到黑板上,所以请参见下面的相应链接 我有多个表,其中一列并不总是标识符列按顺序编号,编号中不应该有任何中断。我的目标是确保这是真的 肮脏的 我们有一个“事件”表,在该表中,我们随机选择一定百分比的行,并将行插入表“结果”中。“Results”中的ID列被传递给一组delete查询 这或多或少确保了多个表中缺少行 我的问题是: 找出一个sql查询,它将对我指定的列重新编号。我宁愿不放弃这个专栏 删除查询示例: de

我已经研究并意识到我有一个独特的情况

首先,由于我是一个新用户,我还不允许将图片发布到黑板上,所以请参见下面的相应链接

我有多个表,其中一列并不总是标识符列按顺序编号,编号中不应该有任何中断。我的目标是确保这是真的

肮脏的 我们有一个“事件”表,在该表中,我们随机选择一定百分比的行,并将行插入表“结果”中。“Results”中的ID列被传递给一组delete查询

这或多或少确保了多个表中缺少行

我的问题是: 找出一个sql查询,它将对我指定的列重新编号。我宁愿不放弃这个专栏

删除查询示例:

delete ItemVoid
from ItemTicket
join ItemVoid
on ItemTicket.item_ticket_id = itemvoid.item_ticket_id
where itemticket.ID in (select ID
            from results)
之前的示例表:

以下表格后面的示例:

如您所见,根据ID列从两个表中删除了2行。现在我要弄清楚如何对item\u ticket\u id和item\u void\u id列重新编号,其中较高的数字减少为缺少的值,下一个最高的数字减少,等等。问题2,如果item\u ticket\u id更改以便在ItemTickets中顺序排列,那么 它必须更新ItemVoid的item\u ticket\u id中的更改


我非常感谢您在这方面提供的任何建议。

既然您正在寻找这方面的建议,我的建议是您需要重新设计,因为我发现您的设计中有一个很大的缺陷

不要删除记录,然后对其余记录重新编号,而是使用位标志将记录标记为非活动。然后,在查询记录时,只需包含WHERE子句,以仅包括活动的记录:

SELECT *
FROM yourTable
WHERE Inactive = 0
这样你就不用担心重新给记录编号了。这还使您能够返回并查看本应删除的记录,并且不会丢失历史记录

如果确实要删除记录并对其重新编号,则可以通过以下方式执行此任务:

创建一个新表 使用新数字将原始数据插入新表 放下你的旧桌子 用正确的数字重命名新表 正如您所看到的,重新编号记录需要很多步骤。当您可以只执行位标志的更新时,您将以这种方式创建更多的工作

您可以将删除查询更改为类似以下内容:

UPDATE ItemVoid
SET InActive = 1
FROM ItemVoid
JOIN ItemTicket
    on ItemVoid.item_ticket_id = ItemTicket.item_ticket_id
WHERE ItemTicket.ID IN (select ID from results)

位标志更容易,这将是我推荐的方法

您正在寻找的函数是一个窗口函数。在标准SQL Server MySQL中,函数是row_number。您可以按如下方式使用它:

select row_number() over (partition by <col>)
from <table>
为了在您的案例中使用此功能,您需要从表中删除行,然后使用with语句重新计算行号,然后使用update分配它们。为了事务完整性,您可以将删除和更新打包到单个事务中

Oracle支持类似的功能,但语法有点不同。Oracle将这些函数称为分析函数,它们支持更丰富的操作集

我强烈警告您不要使用游标,因为它们的性能很差。当然,这对标识列不起作用,因为这样的列无法修改。

回答了一个老问题,因为这是我查找此列时的第一个搜索结果 MS T-SQL

要对ID列(而不是具有间隙的标识列)重新排序, 只能使用带有行号的简单CTE生成新序列。 更新通过CTE“虚拟表”工作,没有任何额外问题,实际上是更新底层原始表。 不要担心ID字段在更新过程中会发生冲突,如果您想知道当设置了已经存在的ID时会发生什么,那么 不会遇到这个问题-原来的序列一次更改为新序列

WITH NewSequence AS
(
  SELECT
    ID, 
    ROW_NUMBER() OVER (ORDER BY ID) as ID_New
  FROM YourTable
)
UPDATE NewSequence  SET ID = ID_New;

在我看来,这似乎是一个设计缺陷,不是删除行,而是使用位标志将它们标记为非活动,然后从查询中排除。那么你不需要在每次删除后对记录重新编号。你好,戈登,你有没有一个使用WITH命令的示例,你不需要为我做这些工作,我只需要一个通用的示例。选项2作为最后的手段,我只需重新对行进行编号,以确保顺序编号的完整性,而不管新的ID号是否位于新的数据行中。太棒了!对于使用此查询的用户,请记住添加一个WHERE,以仅影响表中的某些行。