Поскольку вы не пометили свой вопрос конкретной СУБД, мне придется ответить в целом.
Сам по себе SQL не обеспечивает базовую операцию, которую вы ищете, которая в основном являетсяразделение строк.Это означает, что вам придется написать свой собственный или использовать один из много , которые были опубликованы в Интернете.
Однако вы немного усложнили вопросы с диапазонами, которыеу вас есть в ваших данных.Это означает, что ваша процедура будет выглядеть примерно так:
- Вставьте ваши данные в таблицу temp / memory и выполните итерацию по ней процедурно (или, альтернативно, используйте курсор, чтобы сделать то же самое)
- Для каждой записи в вашем наборе извлеките ненормализованные строковые данные и разделите их на
','
. - Для каждого элемента в разделенных данных вам придется затем разделить что на
'-'
(что для элементов вне диапазона должно возвращать вам один результат). - Если ваше второе разбиение (
'-'
) дает один результат, это одна записьчто вы можете вставить в ваш конечный пункт назначения.Если он дает два результата, то это диапазон, и вам придется выполнять итерации от начала до конца (используя элементы 1 и 2 этого разделения) и вставлять записи в конечный пункт назначения
Редактировать после комментария
К сожалению, я не знаком с PROC SQL или SAS, поэтому не могу предоставить для этого конкретного решения.Я могу опубликовать что-то ниже в SQL Server T-SQL, что, надеюсь, поможет вам начать.
declare @results table (idx int identity(1, 1), id varchar(5), data varchar(max))
declare @elements table (idx int identity(1, 1), element varchar(25))
declare @range table (idx int identity(1, 1), element varchar(25))
insert into @results (id, data)
select
your_id,
your_data
from your_source
declare @i int
declare @cnt int
declare @j int
declare @cnt2 int
declare @element varchar(25)
declare @first int
declare @second int
declare @start int
declare @end int
declare @id varchar(5)
declare @data varchar(max)
select @i = min(idx) - 1, @cnt = max(idx) from @results
while @i < @cnt
begin
select @i = @i + 1
select @id = id, @data = data from @results where idx = @i
delete @elements
insert into @elements (element)
select
element
from split(@data, ',')
select @j = min(idx) - 1, @cnt2 = max(idx) from @elements
while @j < @cnt2
begin
select @j = @j + 1
select @element = element from @elements where idx = @j
delete @range
insert into @range (element)
select
element
from split(@element, '-')
select @first = min(idx), @second = max(idx) from @range
if @first = @second --single element
insert into final_destination (id, value)
select
@id,
element
from @range
else if @second - @first = 1 -- two elements, as desired
begin
select @start = convert(int, element) - 1 from @range where idx = @first
select @end = convert(int, element) from @range where idx = @second
while @start < @end
begin
select @start = @start + 1
insert into final_destination (id, value)
values (@id, @start)
end
end
else -- error condition, bad input
end
end