先建一个临时表,表结构与table表完全一样,再把table表中数据插入到临时表(假设你的ID字段是自增的,数据插入临时表时不指定ID字段),然后DROP原来的table表,再把临时表改名为table。
当然,如果table.ID是另一个表的外键时,还要做相应的处理。

解决方案 »

  1.   

    汗,和这个表关联的数据表,至少在1000W条记录以上,你修改了那么多ID后,改一次,想改死人啊
      

  2.   

    to my_web 
        因为记录删除后,会有空的留下,ID,数目有限制,到最大值后,会从已删除的结点中选一个来使用
      

  3.   


    create table lk7(
    id int not null auto_increment primary key,
    num int
    ) engine = myisam;insert into lk7(num) values
    (1),(2),(4),(6),(10),
    (3),(5),(7),(8),(9);create temporary table tmp select num  from lk7 order by num asc;
    select * from tmp;
    query result(10 records)
    num 









    10 
      

  4.   

    to yueliangdao0608 
    我晕了,我是数据库里已有 1),(2),(4),(6),(10),当然这个值是为固定的,只是举个例子而已
    我想得到 {3),(5),(7),(8),(9);这组数据是预先不可知的 根据已有的记录可以判断出来的
    用一个循环当然是可以取出数据的
       我想问的是有没有简单的方法
      

  5.   

    假设原来的表示a,建立一个1-max(id)的临时表,这个id肯定是连续的,这个表为b,然后a和b连接,select b.id from a,b where a.id!=b.id;这个查出来就是楼主想要的那些。
    是不是这个意思了
      

  6.   


    set @kid=1; select id,body,@kid:=@kid+1 as kid from a where id < @kid+1 order by kid desc limit 1;
      

  7.   

    测试数据是这样的
    a表 id,body 两字段.
    30w数据量
    删除了id为 295010和295027 的数据
     以下为查询语句及其结果.
    第一句查询到删除条的前一数据.
    如果你比较懒可以直接使用第二条拿到已删除编号.
    这种方法只能取出最小的被删除编号.
    同样也可以重新构造取出最大的被删除编号.mysql> set @kid=1; select id,body,@kid:=@kid+1 as kid from a where id < @kid+1 order by kid desc limit 1;
    Query OK, 0 rows affected+--------+------+--------+
    | id     | body | kid    |
    +--------+------+--------+
    | 295009 | abbs | 295010 |
    +--------+------+--------+
    1 row in setmysql> set @kid=1; select id+1,@kid:=@kid+1 as kid from a where id < @kid+1 order by kid desc limit 1;
    Query OK, 0 rows affected+--------+--------+
    | id+1   | kid    |
    +--------+--------+
    | 295010 | 295010 |
    +--------+--------+
    1 row in set
      

  8.   

    忘了最后要回答你的问题了.
    得到这个编号(295010)后
    插入时编号就写 295010.
    然后再取最小已删除编号,插入,补全就可以.
    问题的关键在于找到已被删除的编号有哪些.insert a (id,body) values(295010,'test');
    Query OK, 1 row affected
    set @kid=1; select id+1,@kid:=@kid+1 as kid from a where id < @kid+1 order by kid desc limit 1;
    Query OK, 0 rows affected+--------+--------+
    | id+1   | kid    |
    +--------+--------+
    | 295027 | 295027 |
    +--------+--------+
    1 row in set
      

  9.   

    如果ID是auto_increment
    则不能补
    要补的话必须将auto_increment去掉
    这样应可以补了
    查找ID的号,排序,看哪些ID为空
    看MYSQL里的插入记录是否可以插在某记录前如不能,只有别建新表,倒入,没有记当的ID行暂为空,其他的ID相同时导入
      

  10.   

    To fxs_2008 
    1,MySQL auto_increment 字段可以补,指定空id直接插入即可.
    2,本帖的问题就在于找'ID为空'的地方,所以你是在问还是在答?总结,看帖需要看回帖,回帖需要认真负责.
      

  11.   

    数据库里ID   有值   1,2,4,6,10,我怎么得到3,5,7,8,9,有什么好放法   将他补齐 
    ===================================================================
    在插入之前,如何找到3作为插入数据的id,是问题的关键,也就是找到第一个id连续的断开点。
    建议:加一字段(breakpoint)保存断点标志,默认为null,做删除操作时自动将上一条记录的breakpoint设为1,则插入的id为breakpoint为1的id再加1,更新breakpoint记录,如何数据量大则加一字段未免浪费,可以考虑用文件记录breakpoint的id.如何已经设计成型,现在想补全,问题就是每次插入时如何找到第一个id连续的断开点。
      

  12.   

    to SysTem128:
    接受批评,也期等你的好办法和好思路
      

  13.   

    偶测试了一下
    结果如下:
     1、在id 为auto_increment 的情况下,如果id不存在,可以直接插入
     2、如果id 已存在,插入出错可以做个临时表循环插入,在PHP中操作,如果没有出错,说明这个ID是要补的,记入数组。如查出错,继续循环下一个数!补插时根据数据组中的值直接插入!
    我代码功底不好,大侠给写一个吧! 
      

  14.   

    to SysTem128 
    mysql> set @a = 1;
        -> select c+1,@a:=@a+1 as t from c where c<@a+1 order by c desc limit 1;
        -> //
    Query OK, 0 rows affected (0.00 sec)+-----+------+
    | c+1 | t    |
    +-----+------+
    |   2 |    2 |
    +-----+------+
    1 row in set (0.00 sec)你那个语句不对吧,MYSQL 查出来明显是2,
      

  15.   

    to ideal_1983 
     你的想法倒是可行的,如果实在没办法就用你的一试
      

  16.   

    set @kid=1; select id,body,@kid:=@kid+1 as kid from a where id < @kid+1 order by kid desc limit 1; 这很明显是放在一起的语句,不是两条不相干的语句.@kid需要初始化为1. 这么精良的语句,大量的测试数据,都证明它是正确的.你竟然由于自己的低级错误否定了它,可悲.
      

  17.   

    因为兴趣关系,SysTem128的语句我也测试过,可用~~~~
      

  18.   

    请看一下,下面的测试有何问题,按SYSTEM128程序,应该得出是8,而事实上,我确实得出的是2,难道是因为MYSQL 版本的问题?
    mysql> delimiter //
    mysql> select * from c;//
    +----+
    | c  |
    +----+
    |  1 |
    |  2 |
    |  4 |
    |  3 |
    |  5 |
    |  6 |
    | 10 |
    |  7 |
    |  9 |
    +----+
    9 rows in set (0.00 sec)mysql> set @a = 1;
        -> select c,@a:=@a+1 from c where c<@a+1 order by c desc limit 1;
        -> //
    Query OK, 0 rows affected (0.00 sec)+---+----------+
    | c | @a:=@a+1 |
    +---+----------+
    | 1 |        2 |
    +---+----------+
    1 row in set (0.01 sec)mysql>
      

  19.   


    mysql>set @a=1; 你这样执行,请问这条语句有什么用处?你这里点完回车,下面这句和这个就一点关系都没有了.
        ->select   c,@a:=@a+1   from   c   where   c <@a+1   order   by   c   desc   limit   1; 
        ->//
      

  20.   

    我汗,你没看到我是用//用分隔符,上面的算一句SQL
      

  21.   

    你可以试一下,set @a = 100; 
    然后再回去SELECT @a看看,绝对是100
    而且,我按你的写法,放在一行,结果一样
      

  22.   

    Order By kid 谢谢呀~
      

  23.   

    我日了,还不对,郁闷,老大,你们什么版本的MYSQL
    mysql> select * from c;
        -> //
    +-----+
    | c_f |
    +-----+
    |   1 |
    |   2 |
    |   4 |
    |   3 |
    |   5 |
    |   6 |
    |  10 |
    |   7 |
    |   9 |
    +-----+
    9 rows in set (0.00 sec)mysql> set @a = 1; select c_f,@a:=@a+1 as tmp_id from c  where c_f<@a+1 order by
     tmp_id desc limit 1;
        -> //
    Query OK, 0 rows affected (0.00 sec)+-----+--------+
    | c_f | tmp_id |
    +-----+--------+
    |   3 |      4 |
    +-----+--------+
    1 row in set (0.01 sec)mysql>
      

  24.   

    哦~你需要对id字段也进行排序.
    看来你不知道这个语句是怎么运作的.
    id 字段是自增的 或者说是自然排序的
    @kid 也就构造出一个自然数序列,和记录数同步递增.
    而你的id字段是混序的,所以会取出不和序列的3.
      

  25.   


    mysql> set @a = 1; select c_f,@a:=@a+1 as tmp_id from (select c_f from c order b
    y c_f asc) as c1 where c_f<@a+1 order by  tmp_id desc limit 1;//
    Query OK, 0 rows affected (0.00 sec)+-----+--------+
    | c_f | tmp_id |
    +-----+--------+
    |   7 |      8 |
    +-----+--------+
    1 row in set (0.01 sec)我晕,这样才行,郁闷
    结分了
      

  26.   

    to SysTem128 
       插入新数据后,虽然ID是一样的,但由于存储位置已改变,所以肯定是乱序