sql查询获取已删除的记录

时间:2012-06-19 14:21:39

标签: mysql sql select gaps-and-islands

您的表格table1包含id列,即int(11), not null, auto_increment,从1开始。

假设您有10,000条记录。很明显,最后一条记录的ID是10,000。 删除3条记录后,表中有9,997条记录,但最后一条记录ID值仍为10,000(如果最后一条记录未被删除)。

如何使用1 sql查询显示已删除的记录?

谢谢。

5 个答案:

答案 0 :(得分:5)

我认为最简单的方法是使用只有id的虚拟/临时表。 1-1000然后离开加入那张桌子。

但是一旦完成,请务必从虚拟/临时表中删除“已删除”记录。否则,他们每次都会出现。

<强>&GT;&GT;编辑&lt;&lt; 你可以自己加入来弄清楚你是否缺少ids ....

select a.id + 1 MissingIds
from <table> a
left join <table> b
  on a.id = b.id - 1
where b.id is null
  and a.id < 10000

答案 1 :(得分:2)

答案 2 :(得分:2)

我使用this answer作为参考。

您可以使用以下查询来查找间隙,这实际上将为您提供已删除的记录“范围”。例如,在下面的示例中,在最终结果中返回2行,值为2和3,以及6和7.因此,您知道已删除ID为2到3的行以及包含ID的行已删除6到7个(总共4个已删除的行)。

我相信这符合您在“1 SQL查询”中获得最终结果的要求,而且,没有使用中间表或虚拟表。

delimiter $$
use test
$$

create table mytable (id int not null auto_increment, name varchar(100), primary key (id));
$$

insert into mytable (name) values('a')$$
insert into mytable (name) values('b')$$
insert into mytable (name) values('c')$$
insert into mytable (name) values('d')$$
insert into mytable (name) values('e')$$
insert into mytable (name) values('f')$$
insert into mytable (name) values('g')$$
insert into mytable (name) values('h')$$


delete from mytable where id = 2$$
delete from mytable where id = 3$$
delete from mytable where id = 6$$
delete from mytable where id = 7$$


SELECT (t1.id + 1) as gap_starts_at
     , (SELECT MIN(t3.id) -1
          FROM mytable t3 
         WHERE t3.id > t1.id) as gap_ends_at
  FROM mytable t1
 WHERE NOT EXISTS (SELECT t2.id FROM mytable t2 WHERE t2.id = t1.id + 1)
HAVING gap_ends_at IS NOT NULL

输出:

gap_starts_at  gap_ends_at
2              3
6              7

答案 3 :(得分:1)

DECLARE @myTestTable1 TABLE
(
id INT IDENTITY(1,1) NOT NULL
,testVal int
)

DECLARE @increment AS int = 1

WHILE (@increment <= 10000)
BEGIN
INSERT INTO @myTestTable1
VALUES (@increment)

SET @increment += 1
 END

DELETE FROM @myTestTable1 WHERE id IN (100,200,300)

--SELECT * FROM @myTestTable1

 ;WITH Missing (missnum, maxid)
 AS
 (
  SELECT 1 AS missnum, (select max(id) from @myTestTable1)
  UNION ALL
   SELECT missnum + 1, maxid FROM Missing
   WHERE missnum < maxid
   )
     SELECT missnum
     FROM Missing
     LEFT OUTER JOIN @myTestTable1 tt on tt.id = Missing.missnum
     WHERE tt.id is NULL
     OPTION (MAXRECURSION 0); 

但这花费了很多时间。我们必须缩短时间。

答案 4 :(得分:1)

首先,我将展示生成10.000条记录的最简单方法。没有大问题查询,没有变量。执行时间:~3ms。 LINK

现在关于我承诺的那个触发器。 LINK

正如您所看到的,创建一个很容易。请记住,触发器不仅更好,不仅不需要各种连接,而且还可以存储日期,用户ID等等(非常可扩展的示例)。 触发连接的主要原因是:你不关心有/有/将会有多少记录。你不需要对大小有严格要求。这就是为什么我称​​ sam yi 的答案不够专业。很抱歉误会,我很确定我们都不想侮辱任何人。

通过创建这个例子,我确实学到了一些东西。希望你也这样做了:)