кроссворды, задачки, головоломки

Сборник задач разного уровня сложности по математике, информатике, физике, химии, программированию, экономике etc. Логические задачи, SQL задачи, решение задач. Задачи с ответами, а также нерешённые задачи.

Petruchek.Info

Минимальный незанятый id

Добавлено: 31.05.08 в 14:18
Метки: sql

Дана таблица с полем id (остальные поля значения не имеют):

CREATE TABLE test (id int not null unique key);

В таблице есть записи с такими id:

INSERT INTO test (id) VALUES (1), (5), (4), (3), (2), (100), (101), (200);

Составить SQL-запрос, возвращающий минимальный незанятый id.

На приведённом наборе данных запрос должен возвращать 6.

СПРЯТАТЬ РЕШЕНИЕ/ОТВЕТ

SELECT min(a.id+1)
FROM `test` a
LEFT JOIN test b ON a.id+1 = b.id
where b.id is null


Вместо min() можно использовать order by a.id limit 1
источник

Комментарии
Google says:
Ivan (12.12.08):
Что означает здесь "незанятый" ?
   Ответ редакции
Минимальное натуральное число n, для которого запрос select id from test where id=n вернёт пустое множество.
Yaroslav (14.01.09):
У меня лучше работает такой код:
select min(a.id + 1)
from test a
where a.id + 1 not in (select id from test)
   Ответ редакции
Решение с подзапросом проигрывает решению без подзапроса в универсальности.
Victor (11.02.09):
А будет ли считаться корректным решение/ответ, если не будет занято число 1? По-моему, нет.
   Ответ редакции
Кстати, да.
Dim (27.07.09):
Поддерживаю Victor'а: ответ дан на другое задание: "Составить SQL-запрос, возвращающий минимальный незанятый id, больший чем минимальный имеющийся id". И, кстати, id = 0 в таблице нет, так что ответ некорректен и с имеющимся набором данных.
   Ответ редакции
0 — это не натуральное число.
SerikX (05.01.10):
Вот еще один грубый вариант:
IF ((SELECT MIN(id) FROM TEST) <> 1)
SELECT 1
ELSE
SELECT MIN(id+1) FROM test where id+1 NOT IN (SELECT id FROM test)
Аноним (09.02.10):
select min(ID) + 1 minFreeID
from tmp_sns_test t
where
not exists (
select 1 from tmp_sns_test t2 where t2.ID = t.ID + 1
)
Аноним (16.02.10):
Victor (11.02.09)>>>А будет ли считаться корректным решение/ответ, если не будет занято число 1? По-моему, нет.
Ответ редакции>>>Кстати, да.

проверено на микрософте: если не занято число 1, то возвращает тоже 6

итого: без подзапроса не обойтись.
правильный ответ:
(в стандарте микрософта)
SELECT min(a.id+1)
FROM (select id from test union select 0) a
full JOIN test b ON a.id+1 = b.id
where b.id is null

(если конструкция select 0 не поддерживается) то можно так:
SELECT min(a.id+1)
FROM (select id from test union select distinct 0 from test) a
full JOIN test b ON a.id+1 = b.id
where b.id is null
RED (24.02.11):
И все же оригинальное решение просто - Великолепно!
Я смог выполнить задачу(не внимательно прочитав условие) только при помощи 5 операторов.
Банальным перебором.

Молодцы !
Побольше бы таких интересных задач.
pegoopik (09.08.12):
Не шарите:)
Задача решается в одно чтение из таблицы.

WITH Test AS(
SELECT * FROM (VALUES(7),(3),(2),(4),(1),(6),(200))X(Id)
)

SELECT TOP 1 MIN(id+x)OVER()FirstFreeId
FROM (SELECT Id FROM Test
--этот UNION ALL указывает,
--что нас интересуют только id большие нуля
--если известно, что 1 занята он не нужен
UNION ALL SELECT 0
)X,
(VALUES(0),(1))Y(x)--вспомогательная таблица для сравнения соседних строк
GROUP BY id+x --соединяем соседние значения
HAVING COUNT(*)=1 --нет соседнего значения для Id,
AND id+x<>MIN(id) --значит Id+1 - первый свободный Id
Комментарий от новенького:
Новенький является
Новенький не робот
Знаки на картинке: латинские буквы, арабские цифры


Есть на сайте: Онлайн кроссворды Задачи Онлайн игры Блог
Все работы, опубликованные на сайте — авторские, если не указано иное. Перепечатка возможна только с письменного разрешения владельцев ресурса, с обязательной ссылкой на сайт petruchek.info. Пишите нам: . Сайт должен работать в IE, FF, Opera, Safari.

Реклама:

Разработано в студии "Webous"о проектесайта карта

Реклама: