You want to split data based . . You can use recursive CTE to split data and return depth:
;with cte (id, DescriptionItem, Description, depth) as ( select id, cast(left(Description, charindex('.',Description+'.')-1) as varchar(50)) DescriptionItem, stuff(Description, 1, charindex('.',Description+'.'), '') Description, 1 as depth from MyTable union all select id, cast(left(Description, charindex('.',Description+'.')-1) as varchar(50)) DescriptionItem, stuff(Description, 1, charindex('.',Description+'.'), '') Description, depth+1 from cte where Description > '' ) select id, DescriptionItem, depth from cte order by id, depth;
See SQL Fiddle with Demo
Or you can use the UDF function, which splits the data:
create FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1)) returns @temptable TABLE (items varchar(MAX), depth int) as begin declare @idx int declare @slice varchar(8000) declare @depth int = 1 select @idx = 1 if len(@String)<1 or @String is null return while @idx!= 0 begin set @idx = charindex(@Delimiter,@String) if @idx!=0 set @slice = left(@String,@idx - 1) else set @slice = @String if(len(@slice)>0) insert into @temptable(Items, depth) values(@slice, @depth) set @String = right(@String,len(@String) - @idx) set @depth = @depth +1 if len(@String) = 0 break end return end;
Then, when you call the function, you will use CROSS APPLY similar to this:
select t.id, c.items description, c.depth from mytable t cross apply dbo.split(t.description, '.') c order by t.id, c.depth;
See SQL Fiddle with Demo