【问题标题】:How do I pivot this in T-SQL?如何在 T-SQL 中旋转它?
【发布时间】:2010-05-28 10:17:42
【问题描述】:

我如何得到这个:

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

非常感谢大家,

马特。

【问题讨论】:

  • 尝试搜索“Pivot T-SQL”——这方面有很多问题。
  • 是的,我有,但问题是我似乎没有可以在聚合函数中使用的字段。即:stackoverflow.com/questions/2928022/…
  • 我上面的评论是对 David M 的评论,而不是 Mitch Wheat 的评论。
  • 马特,这可能会有所帮助:simple-talk.com/sql/t-sql-programming/…
  • 这被否决的任何原因?如果解决方案这么简单,链接只是链接到它...

标签: sql pivot


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    撇开你的表格布局,为了做你不应该使用 PIVOT 的事情,你需要子查询。

    【讨论】:

      【解决方案3】:

      假设您的 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
      

      这将导致输出:

      标识 |简短描述 |详细说明

      1 |煤炭、黄金、钢铁 | BlackCoal、WhiteGold、不锈钢

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

      只有在您设法在显示到 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 语句。正如您当前的情况所见,这会过度杀伤针对您的数据库的事务,此外,它很难被利用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-25
        • 2012-05-08
        • 2010-12-17
        • 2017-04-24
        • 2021-09-18
        • 1970-01-01
        • 2021-11-27
        • 2017-01-20
        相关资源
        最近更新 更多