如何在T-SQL中进行透视?

时间:2010-05-28 10:17:42

标签: sql pivot

我如何得到这个:

entityid    name                 stringvalue
----------- -------------------- --------------------
1           ShortDescription     Coal
1           LongDescription      BlackCoal
1           ShortDescription     Gold
1           LongDescription      WhiteGold
1           ShortDescription     Steel
1           LongDescription      StainlessSteel

成为这个:

entityid    ShortDescription     LongDescription
----------- -------------------- --------------------
1           Coal                 BlackCoal
1           Gold                 WhiteGold
1           Steel                StainlessSteel

我到目前为止的代码是:

    select *
from (select entityid, cast(name as nvarchar(20)) as name, cast(stringvalue as nvarchar(20)) as stringvalue from metapropertyvalue) as d
pivot
(
    max(stringvalue)
    for [name] in ([ShortDescription],[LongDescription])
)
as p

非常感谢大家,

3 个答案:

答案 0 :(得分:0)

将桌子的布局放在一边,为了做你想做的事你不应该使用PIVOT你需要子查询。

答案 1 :(得分:0)

pivot关键字几乎完全用于聚合。您可能必须通过子查询手动执行此操作。

除此之外,您的表布局是真的坏主意。我以前做过这个,我知道很多其他人之前就做过这个,它确实很好。最大的问题是您无法正确定义数据的索引。你应该认真地考虑直接将表格改为你的“旋转”格式,因为这是一种适当的关系风格。

答案 2 :(得分:0)

假设您的DBRM无法更改,这是我在几个解决方法之后可以获得的最接近的数据:

select TOP 1 Id
    , LEFT(ShortDescription, LEN(ShortDescription) - 1) as ShortDescription
    , LEFT(LongDescription, LEN(LongDescription) - 1) as LongDescription
from (
    select Entity_Id as Id
            , (
                select StringValue + N', ' as [text()]
                    from MyEntities
                    where [Name] LIKE N'ShortDescription'
                    FOR XML PATH(N'')
            ) as ShortDescription
            , (
                select StringValue + N', ' as [text()]
                    from MyEntities
                    where [Name] LIKE N'LongDescription'
                    FOR XML PATH(N'')
            ) as LongDescription
        from MyEntities
) e

这将导致输出:

  

Id | ShortDescription | LongDescription

     

1 |煤,金,钢| BlackCoal,WhiteGold,StainlessSteel

我怀疑这是否有效,但我不了解你的情况。

如果您在显示之前将数据格式化为GUI或类似的东西,则只考虑这样做。

顺便说一句,PIVOT的东西和这样的聚合只有在数据由数字组成时才有效。如果您的[Name]StringValue列符合数字,那么还有其他方法可以实现此预期结果。

另一方面,我们在这里面临着设计气味。

除了在[Name]列中始终提及它是ShortDescription还是LongDescription之外,不是像你那样设计一个表并且总是必须“转动”它并执行一些复杂的代码来从中检索信息。 ,我建议以下方法按照您希望输出数据的方式设计表格,因为这是常态,如果我可以这么说的话。

IF OBJECT_ID(N'MyEntitiesTable') IS NOT NULL
    DROP TABLE MyEntitiesTable
GO

CREATE TABLE MyEntitiesTable (
    EntityId int IDENTITY(1, 1) NOT NULL PRIMARY KEY
    ShortDescription nvarchar(10) NOT NULL
    LongDescription nvarchar(50) NOT NULL
)
GO

insert into MyEntities (ShortDescription, LongDescription) values (N'Coal', N'BlackCoal')
GO
insert into MyEntities (ShortDescription, LongDescription) values (N'Gold', N'WhiteGold')
GO
insert into MyEntities (ShortDescription, LongDescription) values (N'Steel', N'WhiteSteel')
GO

这样,您将需要编写的所有查询内容如下:

select EntityId
        , ShortDescription
        , LongDescription
    from MyEntitiesTable

对于EntityId字段,如果您绝对希望它始终为数字1,则可以省略表创建中的IDENTITIY(1, 1) PRIMARY KEY字段。但是,我强烈建议您将其放在那里,因为它定义了您的主键,并且模型中没有表应该没有主键。

这种首选方法的原因是,对于必须添加到数据表的每个描述,您必须执行两个INSERT语句。这对你的数据库进行的交易过于苛刻,而且很难利用,正如你现在的情况所见。