Поиск пропусков в таблице

У нас тут сегодня на работе возникла гипотетическая потребность найти пропуски в конкретной таблице базы данных. Так как я кроме как с MySQL в последнее время ни с чем не имел, прикинул как бы я решил эту задачу там. Получилось что-то такое:
SELECT id FROM (
    SELECT id, id-@prev AS diff, @prev:=id
    FROM
        (SELECT @prev:=NULL) ``,
        sourceofdata
   ORDER BY id
) `` WHERE diff>1
Внутри есть напрасный запрос «SELECT @prev:=NULL», который там только затем, чтобы решение получилось в одну строку.

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

Может кто-то придумать проще? Не важно для какой СУБД.
21 января 2013 20:08

HiltoN (инкогнито)
21 января 2013, 21:04

В Oracle как-то так:
select * from (
select id,
id - lag(id, 1, 0) over (order by id) as diff
from sourceofdata)
where diff > 1

HiltoN (инкогнито)
21 января 2013, 21:10

Для других баз можно как-то так:
select id
from sourceofdata t1
where not exists (
select 1 from sourceofdata t2
where t1.id = t2.id + 1
) order by id

bolk (bolknote.ru)
21 января 2013, 21:17, ответ предназначен HiltoN

Прочитал про LAG, спасибо! Не работал с аналитическими функциями, буду знать!

bolk (bolknote.ru)
21 января 2013, 21:19, ответ предназначен HiltoN

Тут умножение же таблиц, не сказал бы что так лучше.

HiltoN (инкогнито)
21 января 2013, 21:26, ответ предназначен bolk (bolknote.ru):

Без привязки к конкретной СУБД нельзя сказать, что будет быстрее. Для MySQL скорее ваш первый вариант предпочтительнее, а Oracle вполне себе соптимизирует мой вариант (но аналитические функции всё равно быстрее будут).

Астродроид Женя (efix.livejournal.com)
21 января 2013, 22:46

А что значит "пропуски в таблице"? Это когда id записей должны идти подряд, но есть места, где пропущены номера?
Например 1, 2, 3, 4, 6, 7 -- пропущено 5?

bolk (bolknote.ru)
21 января 2013, 23:13, ответ предназначен Астродроид Женя (efix.livejournal.com):

Да.

masterspammer (masterspammer.livejournal.com)
22 января 2013, 06:43

в лоб:
select t1.id+1 from table_name t1 left join table_name t2 on t2.id=t1.id+1 where t2.id is null

bolk (bolknote.ru)
22 января 2013, 06:45, ответ предназначен masterspammer.livejournal.com:

Это первый вариант, который мне в голову пришёл :) Но тут умножение таблицы на саму себя, вот что плохо.

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)