I have data like below
NumberFrom - NumberTo
1 - 2
3 - 3
5 - 7
...
...
I want to split them as individual rows like below
Number
1
2
3
5
6
7
.
.
.
Please suggest the way to do it.
Thank you
I have data like below
NumberFrom - NumberTo
1 - 2
3 - 3
5 - 7
...
...
I want to split them as individual rows like below
Number
1
2
3
5
6
7
.
.
.
Please suggest the way to do it.
Thank you
I would do this using a recursive CTE:
with cte as (
select numberfrom, numberto
from t
union all
select numberfrom + 1, numberto
from cte
where numberfrom < numberto
)
select numberfrom as number
from cte;
By default, this is limited to ranges of 100, but you can use the maxrecursion
option to support larger ranges if needed.
A recursive CTE less solution would look something like....
Declare @t table (NumberFrom INT , NumberTo INT)
INSERT INTO @t values
(1 , 2),
(3 , 3),
(5 , 7),
(9 , 11)
Select *
from @t t
CROSS APPLY ( SELECT TOP ( IIF(
ABS(t.NumberTo - t.NumberFrom) = 0
, 1
, ABS(t.NumberTo - t.NumberFrom) + 1) )
t.NumberFrom + ROW_NUMBER() OVER (ORDER BY (Select NULL)) - 1 Vals
FROM master..spt_values x CROSS JOIN master..spt_values y
) c
For SQL Server older than 2012
I used IIF() function before, if you are using SQL Server 2005 or 2008 you can use Case statement inside the TOP clause, something like this...
Declare @t table (NumberFrom INT , NumberTo INT)
INSERT INTO @t values
(1 , 2),
(3 , 3),
(5 , 7),
(9 , 11)
Select *
from @t t
CROSS APPLY ( SELECT TOP ( CASE WHEN
ABS(t.NumberTo - t.NumberFrom) = 0
THEN 1
ELSE ABS(t.NumberTo - t.NumberFrom) + 1 END )
t.NumberFrom + ROW_NUMBER() OVER (ORDER BY (Select NULL)) - 1 Vals
FROM master..spt_values x CROSS JOIN master..spt_values y
) c
Another option is to use an ad-hoc tally table in concert with a CROSS APPLY.
Example
Select B.*
From YourTable A
Cross Apply (
Select Top (NumberTo-NumberFrom+1) N=NumberFrom-1+Row_Number() Over (Order By (Select NULL))
From master..spt_values n1 ,master..spt_values n2
) B
Note: remove ,master..spt_values n2
if the span will not exceed 2,500.
Returns
N
1
2
3
5
6
7
Try This approach
DECLARE @T TABLE
(
NumRange VARCHAR(20)
)
INSERT INTO @T
VALUES('1-2'),('5-7'),('3-3')
;WITH CTE
AS
(
SELECT
StrtVal = CAST(SUBSTRING(NumRange,1,CHARINDEX('-',NumRange)-1) AS INT),
ENdVal = CAST(SUBSTRING(NumRange,CHARINDEX('-',NumRange)+1,LEN(NumRange)) AS INT)
FROM @T
UNION ALL
SELECT
StrtVal = StrtVal+1,
ENdVal
FROM CTE
WHERE StrtVal<ENdVal
)
SELECT
StrtVal
FROM CTE
ORDER BY StrtVal