First you need to create a Table Valued function which takes start and end value to generate the sequence.This is done using recursive cte
CREATE FUNCTION FnGetRange(@startValue int,@endValue int)
RETURNS @rtnTable TABLE
(
generatedVal VARCHAR(MAX)
)
AS
BEGIN
;with cte(startValue,rangeVal,generatedVal)
as
(
Select @startValue,@endValue,@startValue as generatedVal
union all
Select startValue, rangeVal, generatedVal+1
from cte r
where rangeVal > generatedVal
)
Insert into @rtnTable
Select generatedVal from cte
return
END
You need to split the single column into rows so that you can get the range and pass it to the function
;with cte(range) as
(
SELECT
RIGHT(LEFT(T.rangeVal,Number-1),
CHARINDEX(',',REVERSE(LEFT(','+T.rangeVal,Number-1)))) as range
FROM
master..spt_values,
yourTable T
WHERE
Type = 'P' AND Number BETWEEN 1 AND LEN(T.rangeVal)+1
AND
(SUBSTRING(T.rangeVal,Number,1) = ',' OR SUBSTRING(T.rangeVal,Number,1) = '')
)
The above solution was posted here which basically uses master..spt_values to generate the sequence
The cte will return the result like
range
10-15
20-22
25-26
Now you need to split the range into StartValue and EndValue
rangeCte (startValue,endValue) as
(
Select parsename(replace(range,'-','.'),2) as startValue,
parsename(replace(range,'-','.'),1) as endValue
from cte
)
The above rangeCTE will return data like
startValue endValue
10 15
20 22
25 26
Once you get these values you just need to pass it to the function FnGetRange using cross apply
RowValue (rangeSep) as
( Select val.generatedVal as rangeSep from rangeCte r
CROSS APPLY
dbo.FnGetRange(r.StartValue,r.endValue) AS val
)
This will generate the sequence but it will be in multiple rows .To convert it into Single row use xml path
SELECT STUFF(
(SELECT ',' + rangeSep
FROM RowValue
FOR XML PATH(''),type).value('.','varchar(max)'),1,1,'')
Now combining all the CTE's the final query is
;with cte(range) as
(
SELECT
RIGHT(LEFT(T.rangeVal,Number-1),
CHARINDEX(',',REVERSE(LEFT(','+T.rangeVal,Number-1)))) as range
FROM
master..spt_values,
yourTable T
WHERE
Type = 'P' AND Number BETWEEN 1 AND LEN(T.rangeVal)+1
AND
(SUBSTRING(T.rangeVal,Number,1) = ',' OR SUBSTRING(T.rangeVal,Number,1) = '')
),rangeCte (startValue,endValue) as
(
Select parsename(replace(range,'-','.'),2) as startValue,
parsename(replace(range,'-','.'),1) as endValue
from cte
),RowValue (rangeSep) as
( Select val.generatedVal as rangeSep from rangeCte r
CROSS APPLY
dbo.FnGetRange(r.StartValue,r.endValue) AS val
)
SELECT STUFF(
(SELECT ',' + rangeSep
FROM RowValue
FOR XML PATH(''),type).value('.','varchar(max)'),1,1,'')
The result will be
10,11,12,13,14,15,20,21,22,25,26
As others have suggested ,you should seriously change the table design .Instead of storing it as a string create columns to store the range of type int
Updated
Just to be on the same page . You create Insert Trigger on the source table which contains values like 10-15,20-22,25-26.You need to convert these values into sequence and insert it into Target table.If this is the case you can use the below code.
Basically the trigger created Derived Table which inserts data from the inserted which are logical tables in trigger.Then using the above nested CTE's ,you insert the sequence in the target table
create trigger tri_inserts on a
after insert
as
set nocount on
Declare @RangeTable table
(rangeVal varchar(max))
Insert into @RangeTable
Select rangeColumn from INSERTED
;with cte(range) as
(
SELECT
RIGHT(LEFT(T.rangeVal,Number-1),
CHARINDEX(',',REVERSE(LEFT(','+T.rangeVal,Number-1)))) as range
FROM
master..spt_values,
@RangeTable T
WHERE
Type = 'P' AND Number BETWEEN 1 AND LEN(T.rangeVal)+1
AND
(SUBSTRING(T.rangeVal,Number,1) = ',' OR SUBSTRING(T.rangeVal,Number,1) = '')
),rangeCte (startValue,endValue) as
(
Select parsename(replace(range,'-','.'),2) as startValue,
parsename(replace(range,'-','.'),1) as endValue
from cte
),RowValue (rangeSep) as
( Select val.generatedVal as rangeSep from rangeCte r
CROSS APPLY
dbo.FnGetRange(r.StartValue,r.endValue) AS val
)
Insert into Target(DestColumn) --Change the target name
SELECT STUFF(
(SELECT ',' + rangeSep
FROM RowValue
FOR XML PATH(''),type).value('.','varchar(max)'),1,1,'')
GO