答案 0 :(得分:2)
UnPivot当然可以提高性能,但是如果您想在不实际使用Dynamic SQL的情况下动态取消数据透视,请考虑以下内容
示例
Select A.fruiteater
,C.*
From fruits A
Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
Cross Apply (
Select Item = a.value('local-name(.)','varchar(100)')
,Value = a.value('.','varchar(max)')
From B.XMLData.nodes('/row') as C1(n)
Cross Apply C1.n.nodes('./@*') as C2(a)
Where a.value('local-name(.)','varchar(100)') not in ('fruiteater','OtherColumnsToExclude')
) C
返回
fruiteater Item Value
Aaron Fruit1 Orange
Aaron Fruit2 Pear
Aaron Fruit3 Apple
Bob Fruit1 Apple
Bob Fruit2 Orange
Bob Fruit3 Blueberries
Bob Fruit4 Peach
Bob Fruit5 Mango
Bob Fruit6 Banana
Carter Fruit1 Pear
Carter Fruit2 Orange
Carter Fruit3 Apple
David Fruit1 Blueberries
Earnest Fruit1 Mango
Earnest Fruit2 Orange
Earnest Fruit3 Pear
Earnest Fruit4 Apple
Earnest Fruit5 Blueberries
Frank Fruit1 Raspberries
答案 1 :(得分:1)
您可能想使用Unpivot获得预期的结果。
create table fruits (fruiteater varchar(100), Fruit1 varchar(100), Fruit2 varchar(100),
Fruit3 varchar(100), Fruit4 varchar(100), Fruit5 varchar(100), Fruit6 varchar(100))
insert into fruits values ('Aaron', 'Orange', 'Pear', 'Apple', NULL, NULL, NULL)
,('Bob', 'Apple', 'Orange', 'Blueberries', 'Peach', 'Mango', 'Banana')
,('Carter', 'Pear', 'Orange', 'Apple', NULL, NULL, NULL)
,('David', 'Blueberries', NULL, NULL, NULL, NULL, NULL)
,('Earnest', 'Mango', 'Orange', 'Pear', 'Apple','Blueberries', NULL)
,('Frank', 'Raspberries', NULL, NULL, NULL, NULL, NULL)
由于所有这些结果都将放在一列中,因此在进行数据透视时要注意数据类型和长度非常重要,因此我确保所有列都属于同一数据类型。
select fruiteater, Value as Fruit from fruits
unpivot
(value for columnname in ([Fruit1], [Fruit2], [Fruit3], [Fruit4], [Fruit5],[Fruit6]))unpvt
输出:Unpivot将处理空值,因为它消除了这一点。
fruiteater Fruit
Aaron Orange
Aaron Pear
Aaron Apple
Bob Apple
Bob Orange
Bob Blueberries
Bob Peach
Bob Mango
Bob Banana
Carter Pear
Carter Orange
Carter Apple
David Blueberries
Earnest Mango
Earnest Orange
Earnest Pear
Earnest Apple
Earnest Blueberries
Frank Raspberries
答案 2 :(得分:1)
为此,我更喜欢使用横向连接(apply
)。我认为语法更简单,除非您明确希望它能够执行以下操作,否则它不会做任何“魔术”操作,例如删除NULL
值:
select f.fruiteater, v.fruit
from fruits f cross apply
(values (fruit1), (fruit2), (fruit3), (fruit4), (fruit5), (fruit6)
) v(fruit)
where v.fruit is not null;
更重要的是,unpivot
是出于一种目的的非常特定的语法。横向连接非常灵活和强大。用它们来进行透视是了解它们的一种非常简单的方法。