Mysql 获取已删除记录的sql查询

Mysql 获取已删除记录的sql查询,mysql,sql,select,gaps-and-islands,Mysql,Sql,Select,Gaps And Islands,您有一个表table1,其中包含id列,即int(11),非空,自动递增,从1开始 假设您有10000条记录。很明显,最后一条记录的id是10000。 删除3条记录后,表中有9997条记录,但最后一条记录id值仍然为10000(如果最后一条记录未被删除) 如何使用1 sql查询显示已删除的记录 谢谢。我认为最简单的方法是有一个只有ID的虚拟/临时表。1-1000然后左键连接到该表 但一旦完成,请确保从虚拟/临时表中删除“已删除”记录。否则,他们每次都会出现 >编辑您可能会发现此sql在此处很有用

您有一个表
table1
,其中包含
id
列,即
int(11),非空,自动递增
,从1开始

假设您有10000条记录。很明显,最后一条记录的id是10000。 删除3条记录后,表中有9997条记录,但最后一条记录id值仍然为10000(如果最后一条记录未被删除)

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


谢谢。

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

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


>编辑您可能会发现此sql在此处很有用

声明@myTestTable1表格
(
id整型标识(1,1)不为空
,testVal int
)
将@increment声明为int=1
而(@incrementI用作参考

您可以使用下面的查询来查找间隙,这本质上会为您提供已删除的记录“范围”。例如,在下面的示例中,您在最终结果中返回了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

首先,我将展示生成10000条记录的最简单方法。无需大量查询,无需变量。执行时间:~3ms

现在谈谈我答应过的那个触发器

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


通过创建此示例,我确实学到了一些东西。希望您也做到了:)

创建一个具有10000个连续值的表,作为查找表。然后从查找中选择目标表中不存在的所有记录。(这将总是比尝试动态生成缺少的ID更快。)如果您的DMB有一个generate_series()类函数(我不认为mysql有),您可以使用它,基于{min,max},而不是一个硬连线的calander表。+1,因为我通过回答它学到了一些新东西:)一个不错的问题:)您真正需要的是一个数字表或在fly@AndriusNaruševičius不同意。有时候,有一个失败证明方法是专业的,而不是一个过于复杂的方法。@AndriusNaruševičius到底有什么不专业的地方?这是不是太快太容易,以至于你不能向你的客户收取很多时间的费用???不要故意粗鲁。请定义“专业”。每种解决方案对每种情况都是独特的。不是说这是最好的解决方案,而是因为它不“专业”而不予考虑是不对的。因为有一个更好的、更具可扩展性/可管理性的解决方案,所以放弃它。。。现在我们在做饭@samyi改进它的一个方法可能是创建一个带有“check_deleted_timestamp”列的实际表,并在检查删除时更新这些记录,或者在删除原始记录时使用触发器更新这些记录——我已经构建了一个UI,以替代模式面板下面的“delimiter”命令(注意“|”)。使用此选项,您可以构建基于触发器的选项。
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