Благодаря образцу данных Ларну я смог опубликовать другой способ сделать это.
Этот способ состоит в создании предложения values
для выбора из динамического SQL.
-- Get the maximum number of columns
DECLARE @ColumnsCount int =
(SELECT MAX(LEN(Path_Data_Values) - LEN(REPLACE(Path_Data_Values, ' / ', ' ')))
FROM YourTAble
)
DECLARE @Sql nvarchar(max) = 'SELECT * FROM (VALUES' +
STUFF(
(
-- Construct the values clause
SELECT ',(''' + REPLACE(data, ' / ', ''',''') + ''')'
FROM
(
-- use Replicate to add the "missing" values to each line
SELECT Path_Data_Values + REPLICATE(' / ', @ColumnsCount - (LEN(Path_Data_Values) - LEN(REPLACE(Path_Data_Values, ' / ', ' ')))) As data
FROM YourTAble
) x
FOR XML PATH('')
), 1, 1, '')
+ ') V (' +
STUFF(
(
-- Construct the values names
SELECT ',' + REPLACE(Path, ' / ', ',')
FROM YourTAble
WHERE LEN(Path) - LEN(REPLACE(Path, ' / ', ' ')) = @ColumnsCount
FOR XML PATH('')
), 1, 1, '')
+ ')';
-- Whenever using dynamic SQL, Print is your best friend
PRINT @Sql
-- this will print, with the sample data provided, the following SQL statement:
-- SELECT * FROM (VALUES('Org','',''),('Org','North Hemisphere',''),('Org','North Hemisphere','Texas'),('Org','Texas','')) V (Root,Hemisphere,State)
-- unremark once print gets you the desired sql
--EXEC(@Sql)
Результат exec(sql)
для данных данного примера будет следующим:
Root Hemisphere State
Org
Org North Hemisphere
Org North Hemisphere Texas
Org Texas
Если вы хотите null
вместо пустых строк, это так же просто, как заменить ''
на null
в построенномдинамический SQL.
Обратите внимание, что для версии 2017 или выше вы можете упростить это, используя string_agg
вместо использованной комбинации stuff
и for xml
.
Вы можете увидеть живое демо на rextester.