Подтвердить что ты не робот

Sql-запрос для получения удаленных записей

У вас есть таблица table1, которая содержит столбец id, то есть int(11), not null, auto_increment и начинается с 1.

Предположим, у вас 10 000 записей. Понятно, что идентификатор последней записи - 10 000. После того, как вы удалили 3 записи, у вас есть 9997 записей в таблице, но последнее значение идентификатора записи по-прежнему составляет 10 000 (если последняя запись не была удалена).

Как отобразить, какие записи были удалены с помощью 1 sql-запроса?

Спасибо.

4b9b3361

Ответ 1

Я думаю, что проще всего было бы иметь таблицу фиктивной/временной таблицы с только идентификаторами. 1-1000, затем левые присоединяются к этой таблице.

Но обязательно удалите "удаленные" записи из вашей таблицы фиктивных/временных файлов, как только вы закончите. В противном случае они будут отображаться каждый раз.

→ EDIT < Вы можете самостоятельно объединиться, чтобы выяснить, нет ли у вас идентификаторов....

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

Ответ 3

Я использовал этот ответ в качестве ссылки.

Вы можете использовать следующий запрос, чтобы найти пробелы, которые по сути предоставят вам "диапазоны" удаленной записи. Например, в приведенном ниже примере вы получаете 2 строки в конечном результате, а значения - 2 и 3, а 6 и 7. Значит, вы знаете, что строки с идентификаторами от 2 до 3 были удалены, а строки с идентификаторами от 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

Ответ 4

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); 

Но это занимает много времени. Мы должны сократить время.

Ответ 5

Итак, для начала, я собираюсь показать самый простой способ генерации 10.000 записей. Нет огромных запросов, никаких переменных. Время выполнения: ~ 3 мс. ССЫЛКА

Теперь о том триггере, который я обещал. ССЫЛКА

Как вы можете видеть, создать его очень просто. Имейте в виду, что триггер лучше не только без необходимости использования разных соединений, но также можно сохранить дату, идентификатор пользователя и т.д. И т.д. (Это очень расширяемый пример). И основной момент триггера над объединениями: вам все равно, сколько записей было/будет/будет. Вам не нужно быть строгим относительно размера. Вот почему я назвал ответ sam yi недостаточно профессиональным. Извините за недоразумение, я почти уверен, что никто из нас не хотел оскорблять кого-либо.

Создав этот пример, я кое-что узнал. Надеюсь, вы тоже сделали:)