How to find “holes” in a table

后端 未结 10 2187
野趣味
野趣味 2020-12-24 04:28

I recently inherited a database on which one of the tables has the primary key composed of encoded values (Part1*1000 + Part2).
I normalized that column, but I cannot ch

相关标签:
10条回答
  • 2020-12-24 05:04

    This solution doesn't give all holes in table, only next free ones + first available max number on table - works if you want to fill in gaps in id-es, + get free id number if you don't have a gap..

    select numb + 1 from temp minus select numb from temp;

    0 讨论(0)
  • 2020-12-24 05:06

    This solution should give you the first and last ID values of the "holes" you are seeking. I use this in Firebird 1.5 on a table of 500K records, and although it does take a little while, it gives me what I want.

    SELECT l.id + 1 start_id, MIN(fr.id) - 1 stop_id
    FROM (table l
    LEFT JOIN table r
    ON l.id = r.id - 1)
    LEFT JOIN table fr
    ON l.id < fr.id
    WHERE r.id IS NULL AND fr.id IS NOT NULL
    GROUP BY l.id, r.id
    

    For example, if your data looks like this:

    ID
    1001
    1002
    1005
    1006
    1007
    1009
    1011
    

    You would receive this:

    start_id   stop_id
    1003       1004
    1008       1008
    1010       1010
    

    I wish I could take full credit for this solution, but I found it at Xaprb.

    0 讨论(0)
  • 2020-12-24 05:14

    Many of the previous answer are quite good. However they all miss to return the first value of the sequence and/or miss to consider the lower limit 100000. They all returns intermediate holes but not the very first one (100001 if missing).

    A full solution to the question is the following one:

    select id + 1 as newid from
        (select 100000 as id union select id from tbl) t
        where (id + 1 not in (select id from tbl)) and
              (id >= 100000)
        order by id
        limit 1;
    

    The number 100000 is to be used if the first number of the sequence is 100001 (as in the original question); otherwise it is to be modified accordingly "limit 1" is used in order to have just the first available number instead of the full sequence

    0 讨论(0)
  • 2020-12-24 05:15
    select ID +1 From Table t1
    where not exists (select * from Table t2 where t1.id +1 = t2.id);
    

    not sure if this version would be faster than the one you mentioned originally.

    0 讨论(0)
提交回复
热议问题