13

table1を含むテーブルがあります。つまり、1から始まります。idint(11), not null, auto_increment

10,000件のレコードがあるとします。最後のレコードのIDが10,000であることは明らかです。3つのレコードを削除すると、テーブルには9,997のレコードがありますが、最後のレコードIDの値は10,000のままです(最後のレコードが削除されていない場合)。

1つのSQLクエリを使用して削除されたレコードを表示するにはどうすればよいですか?

ありがとうございました。

4

5 に答える 5

5

最も簡単なのは、IDだけのダミー/一時テーブルを用意することだと思います。1-1000は、そのテーブルへの結合を残します。

ただし、完了したら、必ずダミー/一時テーブルから「削除された」レコードを削除してください。それ以外の場合は、毎回表示されます。

>>編集<< 自己結合を実行して、IDが不足しているかどうかを確認できます...。

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

このSQLはここで役立つ場合があります http://www.sqlservercurry.com/2009/06/find-missing-identity-numbers-in-sql.html

于 2012-06-19T14:29:10.610 に答える
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 に答える
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 に答える
1

まず、10.000レコードを生成する最も簡単な方法を紹介します。巨大なクエリや変数はありません。実行時間:〜3ms。リンク

今、私が約束したそのトリガーについて。リンク

ご覧のとおり、作成は非常に簡単です。トリガーは、さまざまな結合が不要なだけでなく、日付やユーザーIDなどを保存することもできます(非常に拡張可能な例です)。そして、結合に対するトリガーの主なポイントは、レコードがいくつあったか、あるか、またはいくつになるかは気にしないということです。サイズを厳密にする必要はありません。そういうわけで私は十分に専門的ではないsamyiの答えを呼んだ。誤解して申し訳ありませんが、私たちの誰もが誰かを侮辱したいとは思わなかったと確信しています。

この例を作成することで、私はいくつかのことを学びました。うまくいけば、あなたもやった:)

于 2012-06-19T17:39:11.470 に答える