SQL-запрос для нахождения Недостающих порядковых номеров

Если вы знаете только один язык, независимо от того, насколько хорошо вы его знаете, вы не великий программист.

Кажется, что такое отношение гласит, что если вы действительно хорошо разбираетесь в C #, Java или любом другом языке, который начали изучать, то это все, что вам нужно. Я не верю этому - каждый язык, который я когда-либо изучал, научил меня чему-то новому в программировании, которое я смог вернуть в свою работу со всеми остальными. Я думаю, что любой, кто ограничивает себя одним языком, никогда не будет так хорош, как мог бы.

Это также указывает на определенное отсутствие любознательности и готовности экспериментировать, что не обязательно соответствует качествам, которые я ожидал бы найти в действительно хорошем программисте.

43
задан Michael 19 October 2017 в 18:05
поделиться

5 ответов

Как насчет чего-то вроде:

  select (select isnull(max(val)+1,1) from mydata where val < md.val) as [from],
     md.val - 1 as [to]
  from mydata md
  where md.val != 1 and not exists (
        select 1 from mydata md2 where md2.val = md.val - 1)

с обобщенными результатами:

from        to
----------- -----------
6           6
8           8
11          14
28
ответ дан 26 November 2019 в 22:54
поделиться

The best solutions are those that use a temporary table with the sequence. Assuming you build such a table, LEFT JOIN with NULL check should do the job:

SELECT      #sequence.value
FROM        #sequence
LEFT JOIN   MyTable ON #sequence.value = MyTable.value
WHERE       MyTable.value IS NULL

But if you have to repeat this operation often (and more then for 1 sequence in the database), I would create a "static-data" table and have a script to populate it to the MAX(value) of all the tables you need.

10
ответ дан 26 November 2019 в 22:54
поделиться

Попробуйте следующее:

declare @min int
declare @max int

select @min = min(seq_field), @max = max(seq_field) from [Table]

create table #tmp (Field_No int)
while @min <= @max
begin
   if not exists (select * from [Table] where seq_field = @min)
      insert into #tmp (Field_No) values (@min)
   set @min = @min + 1
end
select * from #tmp
drop table #tmp
12
ответ дан 26 November 2019 в 22:54
поделиться

Aren't all given solutions way too complex? wouldn't this be much simpler:

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
ответ дан 26 November 2019 в 22:54
поделиться

You could also solve using something like a CTE to generate the full sequence:

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

Hmmmm - the formatting is not working on here for some reason? Can anyone see the problem?

0
ответ дан 26 November 2019 в 22:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: