0

我有一个实体 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
4

1 回答 1

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
于 2013-04-23T14:16:44.160 回答