Вопреки утверждению, что это не может быть сделано с использованием чистого SQL, вот контрольный пример, показывающий, как это можно сделать. (Обратите внимание, что я не говорил, что это было легко - это, однако, возможно.) Предположим, что имя таблицы value_list
со столбцами code
и value
, как показано в правках (почему все забывают включить имя таблицы в вопросе?):
SELECT b.bottom, t.top
FROM (SELECT l1.code - 1 AS top
FROM value_list l1
WHERE NOT EXISTS (SELECT * FROM value_list l2
WHERE l2.code = l1.code - 1)) AS t,
(SELECT l1.code + 1 AS bottom
FROM value_list l1
WHERE NOT EXISTS (SELECT * FROM value_list l2
WHERE l2.code = l1.code + 1)) AS b
WHERE b.bottom <= t.top
AND NOT EXISTS (SELECT * FROM value_list l2
WHERE l2.code >= b.bottom AND l2.code <= t.top);
Два параллельных запроса в предложении from генерируют значения, которые находятся соответственно сверху и снизу пробела в диапазоне значений в таблице. Затем перекрестное произведение этих двух списков ограничивается так, чтобы нижняя часть не превышала верхнюю и чтобы в исходном списке не было значения между нижним и верхним.
На данных выборки получается диапазон 4-6. Когда я добавил дополнительную строку (9, «девять»), он также генерировал диапазон 8-8. Очевидно, у вас также есть два других возможных диапазона подходящего определения «бесконечности»:
-infinity
.. MIN(code)-1
MAX(code)+1
.. +infinity
Обратите внимание:
- Если вы используете это регулярно, в ваших списках обычно не будет много пробелов.
- Пробелы могут появляться только при удалении строк из таблицы (или при игнорировании диапазонов, возвращаемых этим запросом или его родственниками при вставке данных).
- Обычно плохая идея повторно использовать идентификаторы, так что на самом деле эти усилия, вероятно, ошибочны.
Однако, если вы хотите это сделать, вот один из способов сделать это.