8

たとえば、ID 3 を削除すると、次のようになります。

id | name
 1 |
 2 |    
 4 |
 5 |
 ...

ここで、欠落している ID を検索したいと思います。これは、ID を再度入力したいからです。

INSERT INTO xx (id,...) VALUES (3,...)

auto_increment インデックスで「穴」を検索する方法はありますか?

ありがとう!

4

5 に答える 5

16

次のように、ギャップの最高値を見つけることができます。

select t1.id - 1 as missing_id
from mytable t1
left join mytable t2 on t2.id = t1.id - 1
where t2.id is null
于 2012-04-17T10:20:04.037 に答える
3

の目的はAUTO_INCREMENT、行に対して単純で一意で意味のない識別子を生成することです。これらのIDを再利用することを計画するとすぐに、それらは(少なくとも時間内に)一意ではなくなるため、その作業に適したツールを使用していないように思われます。を取り除くことにした場合はAUTO_INCREMENT、同じアルゴリズムですべての挿入を行うことができます。

SQLコードに関しては、このクエリは既存の行を次のIDを持つ行と照合します。

SELECT a.foo_id, b.foo_id
FROM foo a
LEFT JOIN foo b ON a.foo_id=b.foo_id-1

例えば:

 1 NULL
 4 NULL
10 NULL
12 NULL
17 NULL
19   20
20 NULL
24   25
25   26
26   27
27 NULL

したがって、行を除外して最初のギャップを取得するのは簡単です。

SELECT MIN(a.foo_id)+1 AS next_id
FROM foo a
LEFT JOIN foo b ON a.foo_id=b.foo_id-1
WHERE b.foo_id IS NULL

まだ微調整が必​​要なので、これを出発点としてください。

  • 利用可能な最小の数が可能な限り最小の数である場合を考慮する必要があります。
  • 同時挿入を処理するには、テーブルをロックする必要があります。
  • 私のコンピューターでは、大きなテーブルがあると地獄のように遅くなります。
于 2012-04-17T10:41:33.650 に答える
2

これを行う唯一の方法はループを使用することだと思います。他のソリューションでは、1 より大きいギャップは表示されません。

insert into XX values (1)
insert into XX values (2)
insert into XX values (4)
insert into XX values (5)
insert into XX values (10)

declare @min int
declare @max int

select @min=MIN(ID) from xx
select @max=MAX(ID) from xx

while @min<@max begin
    if not exists(select 1 from XX where id = @min+1) BEGIN
        print 'GAP: '+ cast(@min +1 as varchar(10))
    END

    set @min=@min+1
end

結果:

GAP: 3
GAP: 6
GAP: 7
GAP: 8
GAP: 9
于 2012-04-17T10:34:13.303 に答える
0

まず、穴を埋めようとするべきではないというコメントに同意します。単一の SQL ステートメントですべての穴を見つけることはできません。穴が見つかるまで、1 から始まるすべての可能な数字をループする必要があります。これを行うためにSQL関数を作成し、関数で使用できます。したがって、find_first_hole という関数を作成した場合は、次のように挿入で呼び出すことができます。

INSERT INTO xx (id, ...) VALUES (find_first_hole(), ...)
于 2012-04-17T10:21:31.367 に答える
0

これはギャップと島の問題です。私の (およびその他の) 返信をこちらこちらでご覧ください。ほとんどの場合、ギャップと島の問題は、mysql では利用できない再帰 CTE を使用して最もエレガントに解決されます。

于 2012-04-17T10:49:35.633 に答える