2010-05-28 69 views
0

我如何获得这样的:如何在T-SQL中实现这一点?

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 

非常感谢大家,

马特。

+0

尝试搜索“透视T-SQL” - 有这个许多问题。 – 2010-05-28 10:19:19

+0

是的,我有,但问题是我似乎没有一个我可以在聚合函数中使用的字段。即:http://stackoverflow.com/questions/2928022/what-if-i-dont-have-a-column-i-can-use-as-an-aggregate-function-in-my-t-sql- pivo – 2010-05-28 10:20:12

+0

我上面的评论是回应大卫M的评论,而不是米奇小麦的。 – 2010-05-28 10:22:54

回答

0

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

那边,你的表格布局是真的不好主意。我之前做过这件事,我知道很多其他人以前做过这件事,它的确不是,而是。最大的问题是你无法正确定义数据的索引。你应该认真考虑只是直接将表格更改为“pivoted”格式,因为这是一个适当的关系风格。

0

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

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 |长描述

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

我怀疑这是功能性的,虽然我不知道你的情况。

只有在设法将数据格式化为显示到GUI之前,才考虑这么做。

顺便说一下,当数据由数字组成时,PIVOT的东西和这样的聚合只会起作用。如果你的[Name]StringValue列是数字的话,会有其他的方法来达到这个效果。

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

除了像你一样设计一个表格,并且总是必须“旋转”它并且执行一些复杂的代码来从中检索信息,除了在[Name]列中总是提及它是ShortDescription还是一个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语句。这是对你的数据库的交易过度使用,加上,使你很难被利用,就像你可以看到你的现状一样。