SQL 服务器 - Unpivot(双)或交叉申请双 Unpivot?

SQL Server - Unpivot (double) or Cross Apply for Double Unpivot?

我正在尝试弄清楚如何有效地进行双重逆轴旋转。

我知道Unpivot;它采用选定的列(Wizards、Apples、Bananas、Books)并将它们塞进两列,通常是分类描述符和值本身——这两个新列需要名称(Stuff_type、Stuff_count ).

有时虽然您有一组列并且想对它们都进行逆透视。如

    apple_count, apple_weight, wizard_count, wizard_weight, book_count, book_weight
        1,           12.0,         2,           23.0,           3,        34.0

是否有一种有效的方法来取消对这两列的透视?所以本质上你会 return 以下内容:

Item_Name, Item_Weight, Item_Count
apple         12.0          1
wizard        23.0          2

这需要两个逆轴,还是有更有效的方法?

在这里交叉应用会不会更优雅?

这是一个选项,可以 "dynamically" 在不实际使用 Dynamic SQL 的情况下对数据进行反透视。我在这里使用了一个辅助 TVF,但它可以很容易地转换成 CROSS APPLY

例子

Select Item_Name   = left(Item,charindex('_',Item+'_')-1)
      ,Item_Weight = max(case  when Item like '%_weight' then convert(decimal(10,1),Value) end)
      ,Item_Count  = max(case  when Item like '%_count'  then convert(int,Value) end)
 From   YourTable A
 Cross Apply [dbo].[tvf-XML-UnPivot-Row]((Select A.* for XML Raw)) b
 Group By left(Item,charindex('_',Item+'_')-1)

Returns

Item_Name   Item_Weight Item_Count
apple       12.0        1
book        34.0        3
wizard      23.0        2

感兴趣的函数

CREATE FUNCTION [dbo].[tvf-XML-UnPivot-Row](@XML xml)
Returns Table 
As
Return ( 
        Select Item  = xAttr.value('local-name(.)', 'varchar(100)')
              ,Value = xAttr.value('.','varchar(max)')
         From  @XML.nodes('//@*') xNode(xAttr)
)

/*
Select A.ID
      ,B.*
 From  YourTable A
 Cross Apply [dbo].[tvf-XML-UnPivot-Row]((Select A.* for XML RAW)) B
*/