【问题标题】:PIVOT for two fields of different data types不同数据类型的两个字段的 PIVOT
【发布时间】:2013-04-23 14:08:07
【问题描述】:

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

【问题讨论】:

  • 为什么需要将其转换为float 才能最终显示?为什么不将数据保留为 varchar?
  • @bluefeet 因为在我的系统中,这些数字用于报告中。为了讨论的目的,我在这里简化了数据

标签: sql performance sql-server-2008 pivot


【解决方案1】:

抛开设计问题不谈,除非您希望查询返回动态数量的列,否则我并不认为需要使用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

【讨论】:

  • Pivot 不是更有效率吗?
  • @FistOfFury 您必须对其进行测试,但在这种情况下可能不会
  • @Lamak “动态列数”是什么意思?
  • @FistOfFury 关于效率,这将取决于您需要测试此解决方案和PIVOT 之一,但这样我们不会强制转换数据类型。关于“动态列数”,我的意思是,如果您事先不知道有多少属性,但想要每个属性的结果。 (您需要动态 SQL 和 PIVOT
  • @Lamak 我明白了。我并不担心动态更改列数。主要是因为不想打扰动态 SQL,所以我可以控制输出哪些属性及其数据类型。更改包含 PIVOT(或 CASE)的视图不是问题。
猜你喜欢
  • 1970-01-01
  • 2021-01-02
  • 2020-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-13
  • 2019-08-06
相关资源
最近更新 更多