SQL-запрос для поиска отсутствующих порядковых номеров - PullRequest
37 голосов
/ 29 июня 2009

У меня есть столбец с именем sequence. Данные в этом столбце выглядят как 1, 2, 3, 4, 5, 7, 9, 10, 15.

Мне нужно найти пропущенные порядковые номера из таблицы. Какой запрос SQL найдет недостающие порядковые номера из моей таблицы? Я ожидаю результатов, таких как

Missing numbers
---------------
6  
8  
11  
12  
13  
14  

Я использую только одну таблицу. Я попробовал запрос ниже, но не получил желаемых результатов.

select de.sequence + 1 as sequence from dataentry as de 
left outer join dataentry as de1 on de.sequence + 1 = de1.sequence
where de1.sequence is null  order by sequence asc;

Ответы [ 14 ]

0 голосов
/ 01 августа 2014

Создать полезный Счетный стол :

-- can go up to 4 million or 2^22
select top 100000 identity(int, 1, 1) Id
into Tally
from master..spt_values
cross join master..spt_values

Индексируйте это или сделайте этот единственный столбец как PK. Затем используйте EXCEPT, чтобы получить пропущенный номер.

select Id from Tally where Id <= (select max(Id) from TestTable)
except
select Id from TestTable
0 голосов
/ 11 января 2012
DECLARE @TempSujith TABLE
(MissingId int)

Declare @Id Int
DECLARE @mycur CURSOR
SET @mycur = CURSOR FOR Select  Id From tbl_Table

OPEN @mycur

FETCH NEXT FROM @mycur INTO @Id
Declare @index int
Set @index = 1
WHILE @@FETCH_STATUS = 0
BEGIN
    if (@index < @Id)
    begin
        while @index < @Id
        begin
            insert into @TempSujith values (@index)
            set @index = @index + 1
        end
    end
    set @index = @index + 1
FETCH NEXT FROM @mycur INTO @Id
END
Select Id from tbl_Table
select MissingId from @TempSujith
0 голосов
/ 29 июня 2009

Не все ли решения слишком сложны? не будет ли это намного проще:

SELECT  *
FROM    (SELECT  row_number() over(order by number) as N from master..spt_values) t
where   N not in (select 1 as sequence union  
        select 2 union 
        select 3 union 
        select 4 union 
        select 5 union 
        select 7 union 
        select 10 union 
        select 15
        )
0 голосов
/ 29 июня 2009

Вы также можете решить использовать что-то вроде CTE для генерации полной последовательности:

create table #tmp(sequence int)

insert into #tmp(sequence) values (1)
insert into #tmp(sequence) values (2)
insert into #tmp(sequence) values (3)
insert into #tmp(sequence) values (5)
insert into #tmp(sequence) values (6)
insert into #tmp(sequence) values (8)
insert into #tmp(sequence) values (10)
insert into #tmp(sequence) values (11)
insert into #tmp(sequence) values (14)

    DECLARE @max INT
    SELECT @max = max(sequence) from #tmp;

    with full_sequence
    (
        Sequence
    )
    as
    (
        SELECT 1 Sequence

        UNION ALL

        SELECT Sequence + 1
        FROM full_sequence
        WHERE Sequence < @max
    )

    SELECT
        full_sequence.sequence
    FROM
        full_sequence
    LEFT JOIN
        #tmp
    ON
        full_sequence.sequence = #tmp.sequence
    WHERE
        #tmp.sequence IS NULL

Хммм - форматирование здесь не работает по какой-то причине? Кто-нибудь может увидеть проблему?

...