13

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

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

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

谢谢你。

4

5 回答 5

5

我认为最简单的方法是拥有一个只有 id 的虚拟/临时表。1-1000 然后左连接到该表。

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

>> 编辑 << 您可以自行加入以确定您是否缺少 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
于 2012-06-19T14:28:47.603 回答
2

我用这个答案作为参考。

您可以使用以下查询来查找差距,这实质上将为您提供已删除的记录“范围”。例如,在下面的示例中,您在最终结果中返回 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
于 2012-06-19T14:49:38.737 回答
2

您可能会在此处发现此 sql 有用 http://www.sqlservercurry.com/2009/06/find-missing-identity-numbers-in-sql.html

于 2012-06-19T14:29:10.610 回答
1

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

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

如您所见,创建一个非常容易。请记住,触发器不仅不需要各种连接更好,而且您还可以存储日期、用户 ID 等(非常可扩展的示例)。联接触发的要点是:您不在乎曾经/现在/将会有多少条记录。您不需要严格控制尺寸。这就是为什么我称sam yi的回答不够专业。抱歉造成误会,我敢肯定我们都不想侮辱任何人。

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

于 2012-06-19T17:39:11.470 回答
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); 

但这需要很多时间。我们必须减少时间。

于 2012-06-19T14:48:10.923 回答