2009-08-07 175 views
1

有没有办法让一个Entity-Attribute表转换? 我想要将所有行转换为列,而不管有多少个不同的属性。SQL数据透视表

这是我想要完成的一个例子。该示例使用两个属性:FirstName,LastName。但是在真实的数据库中,有数以千计的属性,我想将它们翻转成列以用于报告目的。

我不想为每个属性写一个CTE。

USE TempDB 
DECLARE @Attribute TABLE(
AttributeID Int Identity(10,1) PRIMARY KEY, 
AttributeName Varchar(MAX)) 
INSERT INTO @Attribute(AttributeName) VALUES('Firstname') 
INSERT INTO @Attribute(AttributeName) VALUES('Lastname') 
DECLARE @tbl TABLE(
AttributeID Int, 
EntityValue Varchar(MAX) 
) 
INSERT INTO @tbl(AttributeID,EntityValue) VALUES(10,'John') 
INSERT INTO @tbl(AttributeID,EntityValue) VALUES(10,'Paul') 
INSERT INTO @tbl(AttributeID,EntityValue) VALUES(10,'George') 
INSERT INTO @tbl(AttributeID,EntityValue) VALUES(10,'Ringo') 
INSERT INTO @tbl(AttributeID,EntityValue) VALUES(11,'Lennon') 
INSERT INTO @tbl(AttributeID,EntityValue) VALUES(11,'McCartney') 
INSERT INTO @tbl(AttributeID,EntityValue) VALUES(11,'Harrison') 
SELECT A.AttributeID,AttributeName,EntityValue FROM @tbl T 
INNER JOIN @Attribute A 
ON T.AttributeID=A.AttributeID 


DECLARE @Tbl2 Table(
FirstName Varchar(MAX), 
LastName Varchar(MAX) 
) 
INSERT INTO @Tbl2(FirstName,LastName) VALUES('John','Lennon') 
INSERT INTO @Tbl2(FirstName,LastName) VALUES('Paul','McCartney') 
INSERT INTO @Tbl2(FirstName,LastName) VALUES('George','Harrison') 
INSERT INTO @Tbl2(FirstName) VALUES('Ringo') 
SELECT * FROM @Tbl2 

回答

0

根据您发布的内容,您正在处理SQL Server。

老派的方法是使用IF或CASE语句来表示要创建的每个列。 IE:

CASE WHEN t.AttributeID = 10 THEN t.EntityValue ELSE NULL END 'FirstName' 

的替代方法是使用PIVOT(SQL服务器2005+)。

无论哪种情况,您都必须手动定义输出列。如果你的模型被设置为解决它,你可能会使用动态SQL。

+0

我该怎么做? – 2009-08-07 18:27:15

+1

将CASE更新为与您提供的示例更加一致,但IF/CASE或PIVOT是将行转换为列的唯一方法。 – 2009-08-07 20:19:34

0

如果您很好奇,Microsoft SQL Server的PIVOT运算符不是“动态”的原因,并且您必须指定每个值来枢轴转动,则可以识别PIVOT查询的表结构仅来自查询文本。这是大多数编程语言的重要原则 - 应该可以从表达式中确定表达式的类型。该类型不应取决于表达式中提到的任何内容的运行时值。

也就是说,SQL的某些实现实现了你想要的。例如,我认为Microsoft Access在TRANSFORM中执行此操作。

如果您在网上搜索“动态数据透视表”,您会发现很多。