SQL: выберите минимальное значение, которое еще не существует - PullRequest
9 голосов
/ 06 октября 2010

В таблице A у меня есть столбец int.

Возможно ли использование только оператора select для выбора минимального значения в столбце, которое НЕ СУЩЕСТВУЕТ и превышает 0?

Например, если col имеет значения 1,2,9, оператор выбора вернет 3. Если col имеет 9,10,11, он вернет 1.

Я могу добиться этого, используя временную таблицу или цикл, но мне интересно, могу ли я сделать это, используя только оператор выбора?

Спасибо.

Ответы [ 7 ]

2 голосов
/ 21 октября 2011
select min(id) from (select 1 id from TableA where 1 not in (select id from TableA)  UNION select id + 1  id from TableA where id + 1 not in (select id from TableA) ) as min_ids;
2 голосов
/ 06 октября 2010
select
min(nt.id)
from numbertable nt
left outer join originaldata od
on nt.id=od.id
where od.id is null

имеет таблицу чисел, которая изменяется от 1 до максимального значения (или выше)

2 голосов
/ 06 октября 2010
SELECT MIN(t1.ID+1) as 'MinID'
FROM table t1 LEFT JOIN table t2
On t1.ID+1=t2.ID
Where t2.OtherField IS NULL
1 голос
/ 06 октября 2010
SELECT DISTINCT x + 1 "val"
EXCEPT SELECT DISTINCT x "val"
ORDER BY "val" ASC
LIMIT 1

Как насчет этого?

0 голосов
/ 24 мая 2016

Я продублировал свой ответ от здесь :

SELECT MIN(a.id) + 1 AS firstfree
FROM (SELECT id FROM table UNION SELECT 0) a
LEFT JOIN table b ON b.id = a.id + 1
WHERE b.id IS NULL

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

Единственное, что мне не нравится в этом решении, это то, что дополнительные условия должны быть включены дважды, например:

SELECT MIN(a.id) + 1 AS firstfree
FROM (SELECT id FROM table WHERE column = 4711 UNION SELECT 0) a
LEFT JOIN table b ON b.column = 4711 AND b.id = a.id + 1
WHERE b.id IS NULL

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

0 голосов
/ 06 октября 2010

Попробуйте:

declare @TestTable table (
    col int
)

/* Test Case 1: 1,2,9 */
insert into @TestTable
    (col)
    select 1 union all select 2 union all select 9

SELECT MinValue = (SELECT ISNULL(MAX(t2.col),0)+1
                      FROM @TestTable t2 
                     WHERE t2.col < t1.col)
 FROM @TestTable t1
 WHERE t1.col - 1 NOT IN (SELECT col FROM @TestTable)
   AND t1.col - 1 > 0

delete from @TestTable

/* Test Case 2: 9,10,11 */
insert into @TestTable
    (col)
    select 9 union all select 10 union all select 11

SELECT MinValue = (SELECT ISNULL(MAX(t2.col),0)+1
                      FROM @TestTable t2 
                     WHERE t2.col < t1.col)
 FROM @TestTable t1
 WHERE t1.col - 1 NOT IN (SELECT col FROM @TestTable)
   AND t1.col - 1 > 0
0 голосов
/ 06 октября 2010

попробуйте это: (Обновлено)

    declare @dummy varchar(10)  ;

set @dummy =(select top(1) id from  dbo.b) 

if(   @dummy= '1')
begin
select top(1)l.id + 1 as start
from dbo.b  as l
  left outer join dbo.b  as r on l.id + 1 = r.id
where r.id is null
end
else 
begin
select '1'
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...