値を 1 ずつ増やして挿入する列があります (列は AUTO_INCREMENT ではありません)。ギャップを検索するにはどうすればよいですか。たとえば、列は次のようになります: 1,2,4,5,6 - 欠落している 3 を選択したい。ありがとう!
4 に答える
それは私がそれらのタスクに使用するステートメントです。id
分析するフィールドを表します。
SELECT t1.id+1 AS 'start_seq',
MIN(t2.id) - 1 AS 'end_seq'
FROM yourTable AS t1,
yourTable AS t2
WHERE t1.id < t2.id
GROUP BY t1.id
HAVING 'start_seq' < MIN(t2.id);
これで仕事は完了しますが、より優れたコンパクトなソリューションが他にあるかもしれません。
単純なケース: 最初のギャップのみ
あなたはそれを行うことができます:
SELECT
MIN(seq)
FROM
(SELECT
sequence,
@seq:=@seq+1 AS seq
FROM
t CROSS JOIN (SELECT @seq:=0) AS init) AS gap
WHERE
sequence!=seq
-ここのフィールドsequence
は、ギャップを探している列を指しています。フィドルのデモを見る
さて、よくあるケース。
JOIN
テーブルのサイズが可能なギャップよりも小さい可能性があるため、このようなものを使用することはできません。テーブルが最小値と最大値だけで満たされている状況を想像してみてください。たとえば、1
and 10
- and すべての行を取得したい場合、結果は sequence になります1, 2, ... , 10
。テーブル自体をどのように使用してもJOIN
、テーブルには2行しか存在しないため、2行しか得られません。UNION
もオプションではありません-それを構築する10
場合、一般的なケースでは100
、、、など1000
です。したがって、一般的なケースでは、シーケンステーブルを作成し、およびからの値を入力する必要がありますMIN(sequence)
-MAX(sequence)
そして、LEFT JOINを使用して、好き:
SELECT
full_table.sequence
FROM
full_table
LEFT JOIN t
ON full_table.sequence=t.sequence
WHERE
t.sequence IS NULL
このようなものを試すことができます
SELECT (t1.id + 1) as gap_starts_at,
(SELECT MIN(t3.id) -1 FROM your_table t3 WHERE t3.id > t1.id) as gap_ends_at
FROM your_table t1
WHERE NOT EXISTS (SELECT t2.id FROM your_table t2 WHERE t2.id = t1.id + 1)
HAVING gap_ends_at IS NOT NULL