在保持id连续性的同时从数据库中删除行

时间:2015-08-03 10:58:29

标签: sql sql-server oracle

我有一个包含10行的表格,其中包含1-10。我想删除第5行和第8行,我想要更新ID,以便它们是1-8而不是1-4,6-7和9-10。我不想运行大量的更新语句或手动完成。此外,我需要适用于SQLServer和Oracle数据库的解决方案。我认为像程序这样的东西可以做到这一点,但我不知道如何创建一个或如何去做。

3 个答案:

答案 0 :(得分:3)

戈登·林诺夫指出,你真的不应该这样做。如果你仍然这样做,这里是UPDATE

update t_table t set id = (
    select newid from (
        select id, row_number() over (order by id) newid from t_table
    ) x
    where x.id = t.id
)

语法应该可以在Oracle和MSSQL中使用(仅在Oracle中测试),只要它们允许更新主键即可。 不过,我建议不要使用这种技术。如果您想要一个连续的整数列,请使用row_number(),因为它在上面的查询中用于动态生成一个。

答案 1 :(得分:1)

在Oracle中,它很简单 - 您只需使用MERGE语句以及row_number()分析函数,如下所示:

drop table test1;

create table test1
as
select level id,
       level some_val
from   dual
connect by level <= 10;

delete from test1
where id in (5, 8);

merge into test1 tgt
using (select rowid row_id,
              id,
              row_number() over (order by id) rn
       from   test1) src
  on (tgt.rowid = src.row_id)
when matched then
update set tgt.id = src.rn;

commit;

select * from test1;

        ID   SOME_VAL
---------- ----------
         1          1
         2          2
         3          3
         4          4
         5          6
         6          7
         7          9
         8         10

ETA:我会回应其他人所说的为什么你需要这样做,但是 - 特别是如果id列是主键并且有外键引用它!

答案 2 :(得分:0)

您应该包括您尝试过的内容,无论如何您可以运行此查询,直到不再发生更新(如果您不关心性能,更好地按ID排序并使用行号作为其他答案):

UPDATE myTable t SET id = id - 1 WHERE id <> 1 AND
   NOT EXISTS (SELECT * FROM myTable s WHERE s.id = t.id - 1)