I have a column in which I insert values incremented by one (the column is NOT AUTO_INCREMENT). How can I search for gaps in it, for instance the column goes: 1,2,4,5,6 - I want to select that missing 3. Thanks!

有帮助吗?

解决方案

Simple case: only first gap

You can do that with:

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

-here field sequence is pointing to your column, where you're looking for gap. See fiddle demo

Now, common case.

You can not use just JOIN or something like this, since size of your table may be lesser than possible gap in it. Imagine the situation, when your table is filled with only minimum and maximum value. For example, 1 and 10 - and you want to get all rows, so result will be sequence 1, 2, ... , 10. No matter how you will JOIN your table with itself, you will only get two rows - because only those two exist in your table. UNION is also not an option - since if we'll build that for 10, in common case that can be 100, 1000, e t.c. So for common case you have to create sequence table and fill it with values from MIN(sequence) and MAX(sequence) - and then, using LEFT JOIN, do like:

SELECT
  full_table.sequence
FROM
  full_table
    LEFT JOIN t 
      ON full_table.sequence=t.sequence
WHERE
  t.sequence IS NULL

其他提示

Thats the statement I use for those tasks. id represents the field which you want to analyze.

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

Though this one gets the job done, there might be better and more compact solutions out there.

You can try something like this

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

try this!!

DECLARE @a int
SET @a = SELECT MIN(num) FROM table1
WHILE (SELECT MAX(num) FROM table1 ) > @a
BEGIN
IF @a NOT IN ( SELECT num FROM table1 )
PRINT @a
SET @a=@a+1
END
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top