PIVOT用于两个不同数据类型的字段

时间:2013-04-23 14:08:07

标签: sql performance sql-server-2008 pivot

我有一个实体ID和属性标识符的窄表。对于每一行,都有一个数值或一个字符串。我想转出数据,但这对于不同类型的值字段来说很困难。

目前,我正在将数值转换为文本,然后再将数字转换回数字。这导致格式化问题,我担心它效率低下。这些数据将被大量调用用于计算,这意味着很多转换(更不用说精度损失,可维护性差等)。

我们以这种方式构建表的原因是它允许存储数据的灵活性。并非所有实体都具有所有属性,我们将来可能会添加更多属性。我们不希望表更改影响下游代码。此外,我们实际上并没有在每行中存储属性名称,而是存储整数ID。出于本示例的目的,我使用了字符串而不是数字ID,以便于编码/理解。

透视不同数据类型字段的正确方法是什么?

以下是当前表结构的示例:

declare @temp table
(
    EntityID int,
    AttributeName varchar(500),
    NumberValue float,
    StringValue varchar(500),
    IsText bit
)

insert into @temp (EntityID,AttributeName,NumberValue,StringValue,IsText)
select 1,'Year',1776,null,0

insert into @temp (EntityID,AttributeName,NumberValue,StringValue,IsText)
select 1,'Note',null,'The year our country declared independence',1

insert into @temp (EntityID,AttributeName,NumberValue,StringValue,IsText)
select 2,'Year',1988,null,0

insert into @temp (EntityID,AttributeName,NumberValue,StringValue,IsText)
select 2,'Note',null,'The year Die Hard was released',1

select 
EntityID, YearNum=convert(float, [Year]), Note
from
(
select 
    EntityID,
    AttributeName,
    Value=Case when IsText=1 then StringValue else convert(varchar(500), NumberValue) end
from 
    @temp
) A
pivot
(
    Max(Value) for AttributeName in
    (
        [Year],
        Note
    )
) P

1 个答案:

答案 0 :(得分:3)

除了设计问题之外,我真的不需要使用PIVOT,除非您希望查询返回动态数量的列。否则,你可以这样做:

SELECT  EntityID,
        MAX(CASE WHEN AttributeName = 'Year' THEN NumberValue END) YearNum,
        MAX(CASE WHEN AttributeName = 'Note' THEN StringValue END) Note
FROM @temp
GROUP BY EntityID