( В сторону: почему люди вообще (Рахул, не из-за разного воображения) опускают имя своего стола из вопроса? )
Это очень сложно сделать реляционным способом, потому что он по своей сути опирается на упорядочение данных, а реляционная алгебра работает с (неупорядоченными) множествами. Я полагаю, что мы должны предположить, что столбец DocID не имеет значения, и его нельзя использовать для решения проблемы.
В этом примере у вас есть S003 и S005, и вам не хватает S004. Как мы можем сказать, что отсутствует значение? Предположительно, потому что есть операция сравнения, которая говорит нам «меньше», «равно», «больше чем», а также потому, что есть функция разности, которая говорит нам, что разрыв между S003 и S005 равен 2. Давайте предположим, что « > 'и друзья проводят сравнение (работает здесь для символьных строк), и вы можете создать хранимую процедуру webid_diff (), которая принимает два значения WebID и возвращает разницу.
Затем вы можете написать запрос, такой как:
SELECT a.webid, MIN(b.webid) AS min_next
FROM AnonymousTable AS a, AnonymousTable AS b
WHERE a.webid < b.webid
GROUP BY a.webid;
При этом используется неравенство между таблицей и самой собой, чтобы найти минимальное значение WebID преемника для каждого элемента.
Имея это в качестве ядра, мы можем затем отфильтровать результат, чтобы выбрать только те строки, для которых разрыв между WebID и Min_Next больше одного. Итак, я думаю, что мы получаем ( 1-я попытка) :
SELECT x.webid, y.min_next, webid_diff(x.webid, y.min_next) AS gap
FROM AnonymousTable AS x,
(SELECT a.webid, MIN(b.webid) AS min_next
FROM AnonymousTable AS a, AnonymousTable AS b
WHERE a.webid < b.webid
GROUP BY a.webid
) AS y
WHERE x.webid = y.webid
AND webid_diff(x.webid, y.min_next) > 1;
Действительно ли объединение на внешнем уровне приносит нам что-нибудь полезное? Я так не думаю, поэтому мы можем удалить его, что приведет к ( 2-я попытка) :
SELECT y.webid, y.min_next, webid_diff(y.webid, y.min_next) AS gap
FROM (SELECT a.webid, MIN(b.webid) AS min_next
FROM AnonymousTable AS a, AnonymousTable AS b
WHERE a.webid < b.webid
GROUP BY a.webid
) AS y
WHERE webid_diff(y.webid, y.min_next) > 1;
Это работает . Попытка поместить функцию webid_diff () во внутренний запрос вызывает у меня проблемы - по крайней мере, выражение GAP должно быть включено в предложение GROUP BY, но тогда это даст неправильный ответ.
Предложение HAVING используется для применения условий фильтрации к агрегатам, поэтому выглядит так, будто запрос может быть приведен к:
SELECT a.webid, MIN(b.webid) AS min_next, webid_diff(a.webid, b.webid) AS gap
FROM AnonymousTable AS a, AnonymousTable AS b
WHERE a.webid < b.webid
GROUP BY a.webid
HAVING webid_diff(a.webid, b.webid) > 1;
Однако, это не работает (для меня, с моей СУБД - IBM Informix Dynamic Server), потому что webid_diff () не является агрегатом.
Вот код, который я использовал для функции webid_diff () (которую нужно настроить в соответствии с синтаксисом вашей СУБД) и вспомогательной функции webid_num ():
CREATE FUNCTION webid_num(a CHAR(4)) RETURNING INTEGER;
DEFINE i INTEGER;
LET i = substr(a, 2, 3);
RETURN i;
END FUNCTION;
CREATE FUNCTION webid_diff(a CHAR(4), b CHAR(4)) RETURNING INTEGER;
DEFINE i, j INTEGER;
LET i = webid_num(a);
LET j = webid_num(b);
RETURN (j - i);
END FUNCTION;