How to find “holes” in a table

后端 未结 10 2186
野趣味
野趣味 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 04:50

    This will give you the complete picture, where 'Bottom' stands for gap start and 'Top' stands for gap end:

        select *
        from 
        ( 
           (select <COL>+1 as id, 'Bottom' AS 'Pos' from <TABLENAME> /*where <CONDITION*/>
           except
           select <COL>, 'Bottom' AS 'Pos' from <TABLENAME> /*where <CONDITION>*/)
        union
           (select <COL>-1 as id, 'Top' AS 'Pos' from <TABLENAME> /*where <CONDITION>*/
           except
           select <COL>, 'Top' AS 'Pos' from <TABLENAME> /*where <CONDITION>*/)
        ) t
        order by t.id, t.Pos
    

    Note: First and Last results are WRONG and should not be regarded, but taking them out would make this query a lot more complicated, so this will do for now.

    0 讨论(0)
  • 2020-12-24 04:53
    SELECT (ID+1) FROM table AS t1
    LEFT JOIN table as t2
    ON t1.ID+1 = t2.ID
    WHERE t2.ID IS NULL
    
    0 讨论(0)
  • 2020-12-24 04:54

    For people using Oracle, the following can be used:

    select a, b from (
      select ID + 1 a, max(ID) over (order by ID rows between current row and 1 following) - 1 b from MY_TABLE
    ) where a <= b order by a desc;
    
    0 讨论(0)
  • 2020-12-24 05:00

    The best way is building a temp table with all IDs

    Than make a left join.

    declare @maxId int
    select @maxId = max(YOUR_COLUMN_ID) from YOUR_TABLE_HERE
    
    
    declare @t table (id int)
    
    declare @i int
    set @i = 1
    
    while @i <= @maxId
    begin
        insert into @t values (@i)
        set @i = @i +1
    end
    
    select t.id
    from @t t
    left join YOUR_TABLE_HERE x on x.YOUR_COLUMN_ID = t.id
    where x.YOUR_COLUMN_ID is null
    
    0 讨论(0)
  • 2020-12-24 05:02

    Have thought about this question recently, and looks like this is the most elegant way to do that:

    SELECT TOP(@MaxNumber) ROW_NUMBER() OVER (ORDER BY t1.number) 
    FROM master..spt_values t1 CROSS JOIN master..spt_values t2 
    EXCEPT
    SELECT Id FROM <your_table>
    
    0 讨论(0)
  • 2020-12-24 05:04

    from How do I find a "gap" in running counter with SQL?

    select
        MIN(ID)
    from (
        select
            100001 ID
        union all
        select
            [YourIdColumn]+1
        from
            [YourTable]
        where
            --Filter the rest of your key--
        ) foo
    left join
        [YourTable]
        on [YourIdColumn]=ID
        and --Filter the rest of your key--
    where
        [YourIdColumn] is null
    
    0 讨论(0)
提交回复
热议问题