假设我们有以下XML:
<root>
<row>
<column>row 1 col 1</column>
<column>row 1 col 2</column>
<column>row 1 col 3</column>
</row>
<row>
<column>row 2 col 1</column>
<column>row 2 col 2</column>
<column>row 2 col 3</column>
</row>
<row>
<column>row 3 col 1</column>
<column>row 3 col 2</column>
<column>row 3 col 3</column>
</row>
</root>
如何使用 T-SQL XQuery 将其转换为:
<root>
<column>
<row>row 1 col 1</row>
<row>row 2 col 1</row>
<row>row 3 col 1</row>
</column>
<column>
<row>row 1 col 2</row>
<row>row 2 col 2</row>
<row>row 3 col 2</row>
</column>
<column>
<row>row 1 col 3</row>
<row>row 2 col 3</row>
<row>row 3 col 3</row>
</column>
</root>
答案 0 :(得分:1)
我怀疑使用PIVOT
可能有一个非常好的方法,但我不太清楚它能够肯定地说出来。我在这提供的工作。我把它拆分成块以便更好地格式化并提供评论:
首先让我们捕获示例数据
-- Sample data
DECLARE @x3 xml
SET @x3 = '
<root>
<row>
<column>row 1 col 1</column>
<column>row 1 col 2</column>
<column>row 1 col 3</column>
</row>
<row>
<column>row 2 col 1</column>
<column>row 2 col 2</column>
<column>row 2 col 3</column>
</row>
<row>
<column>row 3 col 1</column>
<column>row 3 col 2</column>
<column>row 3 col 3</column>
</row>
</root>
'
DECLARE @x xml
SET @x = @x3
-- @x is now our input
现在实际的转置代码:
确定矩阵的大小:
WITH Size(Size) AS
(
SELECT CAST(SQRT(COUNT(*)) AS int)
FROM @x.nodes('/root/row/column') T(C)
)
粉碎数据,使用ROW_NUMBER
来捕获索引(-1
使其为零),并对索引使用模数和整数除法来计算 new < / em>行号和列号:
,Flattened(NewRow, NewCol, Value) AS
(
SELECT
-- i/@size as old_r, i % @size as old_c,
i % (SELECT TOP 1 Size FROM Size) AS NewRow,
i / (SELECT TOP 1 Size FROM Size) AS NewCol,
Value
FROM (
SELECT
(ROW_NUMBER() OVER (ORDER BY C)) - 1 AS i,
C.value('.', 'nvarchar(100)') AS Value
FROM @x.nodes('/root/row/column') T(C)
) ShreddedInput
)
有了这个CTE FlattenedInput
,我们现在需要做的就是获得FOR XML
选项和查询结构,我们已经完成了:
SELECT
(
SELECT Value 'column'
FROM
Flattened t_inner
WHERE
t_inner.NewRow = t_outer.NewRow
FOR XML PATH(''), TYPE
) row
FROM
Flattened t_outer
GROUP BY NewRow
FOR XML PATH(''), ROOT('root')
示例输出:
<root>
<row>
<column>row 1 col 1</column>
<column>row 2 col 1</column>
<column>row 3 col 1</column>
</row>
<row>
<column>row 1 col 2</column>
<column>row 2 col 2</column>
<column>row 3 col 2</column>
</row>
<row>
<column>row 1 col 3</column>
<column>row 2 col 3</column>
<column>row 3 col 3</column>
</row>
</root>
适用于任何尺寸的'square'数据。请注意缺乏完整性检查/错误处理。
答案 1 :(得分:0)
SET @x3 = '
<root>
<row>
<column>row 1 col 1</column>
<column>row 1 col 2</column>
<column>row 1 col 3</column>
</row>
<row>
<column>row 2 col 1</column>
<column>row 2 col 2</column>
<column>row 2 col 3</column>
</row>
<row>
<column>row 3 col 1</column>
<column>row 3 col 2</column>
<column>row 3 col 3</column>
</row>
</root>
'
select @x3 = replace(@x3,'<row>','<rowtemp>')
select @x3 = replace(@x3,'<column>','<row>')
select @x3 = replace(@x3,'<rowtemp>','<column>')
select @x3