通过定界符列名和列标题将行转置为列

索普罗诺

我在这个问题上稍有停留,请需要一些SQL帮助。iv从需要帮助的人那里得到了一个层次结构表,并将其放入另一个表的实际列中。这是查询表的示例行。除了从此表结果中进行工作之外,我无权调整其他任何内容:

SELECT ID, Path, Path_Values 
FROM TABLE1

输出:

ID  | Path                      | Path_Data_Values
----+---------------------------+----------------------------------
1   | Root                      | Org
2   | Root / Hemisphere         | Org / North Hemisphere
3   | Root / Hemisphere / State | Org / North Hemisphere / Texas
4   | Root / State              | Org / Texas

上表可以深入到大约10个级别。无论如何,值得庆幸的是,我知道决赛桌的最大深度,而且我可以访问将结果存储在上面的位置,将上面的结果转换为读取路径并为其确定合适的列,然后将值插入到最终表中。

该茶几的直观示例(所需结果):

ID | Root | Hemisphere           | State | Other_1 | Other_2 | Other_3
---+------+----------------------+-------+---------+---------+----------
 1 | Org  | NULL                 | NULL  | NULL    | NULL    | NULL
 2 | Org  | Northern Hemisphere  | NULL  | NULL    | NULL    | NULL
 3 | Org  | Northern Hemisphere  | Texas | NULL    | NULL    | NULL
 4 | Org  | NULL                 | Texas | NULL    | NULL    | NULL
拉努

这将带您到那里。但是,由于数据的定义在行与行之间会发生变化,因此,如果要动态执行操作,则无法按所需顺序获取数据。(例如,示例应处于2或3的位置,因为这两个位置都显示?没有数据或查询表的知识,那是不可能的。这是一个动态解决方案,但是,它向您显示了生成的代码如果您想手动编码所有职位,则可以获得您想要的结果。

这也使用DelimitedSplit8k_LEAD,因为STRING_SPLIT它不提供分隔列表中项目的顺序位置;使其在这里无用。

CREATE TABLE dbo.YourTable (ID int,
                            [Path] varchar(8000),
                            Path_Data_Values varchar(8000));
INSERT INTO dbo.YourTable(ID, [Path], Path_Data_Values)
VALUES (1,'Root','Org'),
       (2,'Root / Hemisphere','Org / North Hemisphere'),
       (3,'Root / Hemisphere / State','Org / North Hemisphere / Texas'),
       (4,'Root / State','Org / Texas');

GO

DECLARE @SQL nvarchar(MAX);

SET @SQL = N'SELECT YT.ID,' + NCHAR(13) + NCHAR(10) +
           STUFF((SELECT N',' + NCHAR(13) + NCHAR(10) + 
                         N'       MAX(CASE P.Item WHEN ' + QUOTENAME(P.Item,'''') + N' THEN PDV.Item END) AS ' + QUOTENAME(P.Item)
                  FROM dbo.YourTable YT
                       CROSS APPLY (VALUES(REPLACE(YT.[Path],' / ','|')))V([Path])
                       CROSS APPLY dbo.DelimitedSplit8K_LEAD(V.[Path],'|') P
                  GROUP BY P.Item
                  FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,3,N'') + NCHAR(13) + NCHAR(10) +
           N'FROM dbo.YourTable YT' + NCHAR(13) + NCHAR(10) +
           N'     CROSS APPLY (VALUES(REPLACE(YT.[Path],'' / '',''|''),REPLACE(YT.Path_Data_Values,'' / '',''|'')))V([Path],Path_Data_Values)' + NCHAR(13) + NCHAR(10) +
           N'     CROSS APPLY dbo.DelimitedSplit8K_LEAD(V.[Path],''|'') P' + NCHAR(13) + NCHAR(10) +
           N'     CROSS APPLY(SELECT DS.Item FROM dbo.DelimitedSplit8K_LEAD(V.Path_Data_Values,''|'') DS WHERE P.ItemNumber = DS.ItemNumber) PDV' + NCHAR(13) + NCHAR(10) +
           N'GROUP BY YT.ID;';

PRINT @SQL;

EXEC sp_executesql @SQL;

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章