Возможно, что-то подобное сработает в вашу пользу. Использование оконных функций LEAD () И LAG () для получения предыдущего и следующего значений строки.
Sql Fiddle
DECLARE @T TABLE(Number INT)
INSERT @T VALUES(12),(15),(10),(40),(20),(5)
SELECT
Number,
NextNumber = ISNULL(LEAD(Number) OVER (PARTITION BY 1 ORDER BY Number),Number),
LastNumber = ISNULL(LAG(Number) OVER (PARTITION BY 1 ORDER BY Number),Number)
FROM
T
Из таблицы нарастания вам необходимо сопоставить входные данные в допустимых диапазонах и выбрать наилучшее соответствие (в этом случае оно ближе всего к началу / концу диапазона).
DECLARE @NumberToSearch INT =23
;WITH Ranges AS
(
SELECT
Number,
RangeStart = ISNULL(LAG(Number) OVER (PARTITION BY 1 ORDER BY Number) ,Number),
RangeEnd = ISNULL(LEAD(Number) OVER (PARTITION BY 1 ORDER BY Number) , Number)
FROM
@T
)
,ApplicableRanges AS
(
SELECT
Number,
RangeStart,
RangeEnd,
Instance = ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY RangeStart)
FROM
Ranges R
WHERE
@NumberToSearch BETWEEN R.RangeStart AND R.RangeEnd
)
SELECT * FROM ApplicableRanges WHERE Instance = 1