2015-06-02 2 views
1

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

В основном я хочу делать противоположные этот вопрос: How to create number ranges from a list of numbers?

Из того, что я прочитал, моя догадка при решении может быть каким-то динамический крест применить, но я не совсем уверен, как даже начать это.

Моя таблица выглядит следующим образом:

Таблица

RangeStart RangeEnd 
200  205 
208  209 
221  221 
222  224 

Я хочу что-то вроде этого:

Желаемая Результат

Sequence 
200 
201 
202 
203 
204 
205 
208 
209 
221 
222 
223 
224 
+0

И вы хотите использовать sql для этого, потому что? – Strawberry

+0

@Strawberry Если единственный инструмент у вас есть молот ... – Rob

ответ

0

можно избежать с помощью таблицы «чисел», с использованием рекурсивного общего табличного выражения:

WITH Numbers AS (
SELECT RangeStart, RangeStart AS Number, RangeEnd from RangeTable 
UNION ALL 
SELECT RangeStart, Number + 1, RangeEnd FROM Numbers WHERE Number < RangeEnd) 
SELECT Number FROM Numbers ORDER BY Number 

Первая часть является «якорь» запроса, который определяет элемент корневого (в данном случае , диапазон от числа, первое число в диапазоне и диапазон до номера).

Вторая часть (после UNION ALL) рекурсивно присоединяется к элементу анкера и по существу сохраняет прибавлением к Number и рекурсии, пока он не достигнет RangeEnd.

Заключительная часть получает только цифры из CTE, которые мы построили (мы больше не заинтересованы в начале и конце диапазона) и убедитесь, что они находятся в правильном порядке (это может не иметь значения для вас, и в этом случае вы можете опустить пункт ORDER BY.)

Редактировать - если вы нажмете предел рекурсии с этим, вы можете исправить это, добавив OPTION (MAXRECURSION 0) в конце запроса. Извинения за это!

+1

Мне нравится этот, но вы можете столкнуться с проблемами с макс рекурсией ... 'Msg 530, Level 16, State 1, Line 13 Инструкция завершена.Максимальная рекурсия 100 была исчерпана до завершения заявки. « –

+0

Я мог бы добавить, что использование CTE для создания диапазонов чисел таким образом имеет несколько преимуществ, не в последнюю очередь из-за того, что он не полагается на присутствие (или доступность) любых «таблиц чисел». Существует хорошее обсуждение различных способов создания диапазонов: http://stackoverflow.com/questions/1393951/what-is-the-best-way-to-create-and-populate-a-numbers-table –

+0

@CrappyCodingGuy - вы можете легко обойти предел максимальной рекурсии, добавив подсказку 'OPTION (MAXRECURSION 0)' в конце запроса –

0

Th Самый простой способ - начать со списка целых чисел. Удобные один - если список не слишком долго - это master..spt_values:

with n as (
     select row_number() over (order by (select null)) - 1 as n 
     from master..spt_values 
    ) 
select (rangestart + n.n) as sequence 
from ranges r join 
    n 
    on r.rangestart + n.n <= r.rangeend 
order by sequence; 

Если вы обеспокоены перекрытиями, то следующий простой способ, чтобы получить последовательность:

select distinct (rangestart + n.n) as sequence 
from ranges r join 
    n 
    on r.rangestart + n.n <= r.rangeend 
order by sequence; 

Если проблема имеет много перекрытий и значений, тогда вам нужен несколько иной подход (но это не вопрос, который вы задаете).

+0

Это также сработало для меня. Спасибо – Rob

0
declare @Sequence table(
    Value int 
) 

declare @Value int = 0 

while (@Value < 500) 
    begin 
    insert @Sequence values(@Value) 
    select @Value += 1 
    end 

select * from @Sequence 

declare @Ranges table(
    RangeStart int, 
    RangeEnd int 
) 

insert into @Ranges values(200, 205) 
insert into @Ranges values(208, 209) 
insert into @Ranges values(221, 221) 
insert into @Ranges values(222, 224) 


select s.Value 
from @Sequence s 
join @Ranges r on r.RangeStart <= s.Value and r.RangeEnd >= s.Value 
order by s.Value 

Ключ получает ваш список значений @Sequence.

Смежные вопросы