Получить недостающий номер sql

В таблице у меня есть поле pwd, которое выглядит так: 001, 002, 003, 004 .

Чтобы получить наибольшее значение, я иду так

 ("SELECT pwd FROM users WHERE pwd= (SELECT max(pwd) FROM users)")

Таким образом, я получил номер 004. Чтобы увеличить его и снова добавить в таблицу, я использую

biggest= CInt((SQLDataset.Tables(0).Rows(0).Item(0)))
Dim test As String = "000" & biggest
txtpwd.Text = test.Substring(test.Length - 3)
test2 = test.Substring(test.Length - 3)

Но что делать, если я хочу найти первый доступный номер (отсутствует один) . Пример если у меня есть

001, 002, 003 ,005 , 006 , 007 , 009 , 013. 

Я хочу взять номер 004, Как я могу это сделать.

3 ответа

Решение

Таким образом, я получу все пропущенные числа в массиве, а затем использую индекс строки 0, чтобы получить только первое.

select u1.pwd+1 as firstmissing
  from users as u1
       left outer join users as u2
                    on u2.pwd=u1.pwd+1
 where u2.pwd is null

Вы можете использовать подзапрос (предполагая sql-сервер):

SELECT MIN(u.pwd) + 1 AS FirstMissing
FROM users u
WHERE (u.pwd + 1) <> (SELECT TOP 1 u2.pwd 
                      FROM users u2
                      WHERE u2.pwd > u.pwd)

демонстрация

Если вы хотите сделать это в памяти, так как у вас уже есть DataSet Вы можете использовать следующий запрос Linq-To-DataSet. Но я настоятельно рекомендую не использовать фильтрацию на стороне клиента.

Dim rows = SQLDataset.Tables(0).AsEnumerable()
Dim missing = From row In rows
              Let id = row.Field(Of Int32)(0)
              Let nextId = rows.Select(Function(r) r.Field(Of Int32)(0)).
                                Where(Function(idNext) idNext > id).
                                OrderBy(Function(idNext) idNext).
                                DefaultIfEmpty(-1).
                                First()
              Where nextId <> -1 AndAlso id + 1 <> nextId
              Select id + 1
Dim firstMissing As Int32 = missing.FirstOrDefault()

Если это на самом деле string в DataTable ты можешь использовать Int32.Parse:

Dim missing = From row In rows
              Let id = Int32.Parse(row.Field(Of String)(0))
              Let nextId = rows.Select(Function(r) Int32.Parse(r.Field(Of String)(0))).
                                Where(Function(idNext) idNext > id).
                                OrderBy(Function(idNext) idNext).
                                DefaultIfEmpty(-1).
                                First()
              Where nextId <> -1 AndAlso id + 1 <> nextId
              Select id + 1

Вы должны обслужить случай для пустого стола.

declare @data table (Value char(3))

select ISNULL(RIGHT('00' + CONVERT(varchar(10), MIN(Number)), 3), '001') AS FirstMissingValue
from
(
    -- Inner Table
    select Value, ROW_NUMBER() OVER (ORDER BY Value) Number 
    from @data
) data
where Value <> Number


insert @data values('001'), ('002'), ('003') ,('008'), ('006')

select ISNULL(RIGHT('00' + CONVERT(varchar(10), MIN(Number)), 3), '001') AS FirstMissingValue
from
(
    -- Inner Table
    select Value, ROW_NUMBER() OVER (ORDER BY Value) Number 
    from @data
) data
where Value <> Number

Результат

FirstMissingValue
-----------------
001

FirstMissingValue
-----------------
004
Другие вопросы по тегам