Based on the following table
ID Path
---------------------------------------
1 \\Root
2 \\Root\Node0
3 \\Root\Node0\Node1
4 \\Root\Node0\Node2
5 \\Root\Node3
6 \\Root\Node3\Node4
7 \\Root\Node5
...
N \\Root\Node5\Node6\Node7\Node8\Node9\Node10
so on...
There are around 1000 rows in this table. I want to display individual nodes in separate columns. Maximum columns to be displayed 5 (ie node till 5 level deep). So the output will look as below
ID Path Level 0 Level 1 Level 2 Level 3 Level 4 Level 5
----------------------------------------------------------------------------------------
1 \\Root Root Null Null Null Null Null
2 \\Root\Node0 Root Node 0 Null Null Null Null
3 \\Root\Node0\Node1 Root Node 0 Node 1 Null Null Null
4 \\Root\Node0\Node2 Root Node 0 Node 2 Null Null Null
5 \\Root\Node3 Root Node 3 Null Null Null Null
6 \\Root\Node3\Node4 Root Node 3 Node 4 Null Null Null
7 \\Root\Node5 Root Node 5 Null Null Null Null
...
N (see in above table) Root Node 5 Node 6 Node 7 Node 8 Node 9
The only way I can think of is to open a cursor, loop through each row and perform a string split, just fetch the first 5 nodes and then insert into a temp table.
Please suggest.
Thanks
What you need is a table-valued split function akin to the following:
CREATE FUNCTION [dbo].[udf_Split] (@DelimitedList nvarchar(max), @Delimiter nvarchar(2) = ',')
RETURNS @SplitResults TABLE (Position int NOT NULL PRIMARY KEY, Value nvarchar(max))
AS
Begin
Declare @DelimiterLength int
Set @DelimiterLength = DataLength(@Delimiter) / 2
If Left(@DelimitedList, @DelimiterLength) <> @Delimiter
Set @DelimitedList = @Delimiter + @DelimitedList
If Right(@DelimitedList, @DelimiterLength) <> @Delimiter
Set @DelimitedList = @DelimitedList + @Delimiter
Insert @SplitResults(Position, Value)
Select CharIndex(@Delimiter, A.list, N.Value) + @DelimiterLength
, Substring (
A.List
, CharIndex(@Delimiter, A.list, N.Value) + @DelimiterLength
, CharIndex(@Delimiter, A.list, N.Value + 1)
- ( CharIndex(@Delimiter, A.list, N.Value) + @DelimiterLength )
)
From dbo.Numbers As N
Cross Join (Select @DelimitedList As list) As A
Where N.Value > 0
And N.Value < LEN(A.list)
And Substring(A.list, N.Value, @DelimiterLength) = @Delimiter
Order By N.Value
Return
End
This function relies on the existence of a Numbers
table which contains a sequential list of integers. Now, you could take your original data and do something like:
With TableData As
(
Select 1 As Id, '\\Root' As [Path]
Union Select All 2, '\\Root\Node0'
Union Select All 3, '\\Root\Node0\Node1'
Union Select All 4, '\\Root\Node0\Node2'
Union Select All 5, '\\Root\Node3'
Union Select All 6, '\\Root\Node3\Node4'
Union Select All 7, '\\Root\Node5'
)
, SplitData As
(
Select T.Id, T.[Path], S.Value
, Row_Number() Over ( Partition By T.Id Order By S.Position ) As Level
From TableData As T
Cross Apply dbo.udf_Split( (Substring(T.[Path],2,Len(T.[Path])) + '\') , '\') As S
)
Select Id, [Path]
, Min( Case When Level = 1 Then S.Value End ) As Level0
, Min( Case When Level = 2 Then S.Value End ) As Level1
, Min( Case When Level = 3 Then S.Value End ) As Level2
, Min( Case When Level = 4 Then S.Value End ) As Level3
, Min( Case When Level = 5 Then S.Value End ) As Level4
From SplitData As S
Group By Id, [Path]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.