【问题标题】:Pivot a fixed multiple column table in sql server在 sql server 中透视一个固定的多列表
【发布时间】:2013-09-02 14:52:07
【问题描述】:

我有一张表,我需要为报告服务进行数据透视:

DateCreated Rands   Units   Average Price   Success %   Unique Users
-------------------------------------------------------------------------
2013-08-26  0       0       0               0              0
2013-08-27  0       0       0               0              0
2013-08-28  10      2       5               100            1
2013-08-29  12      1       12              100            1
2013-08-30  71      9       8               100            1
2013-08-31  0       0       0               0              0
2013-09-01  0       0       0               0              0

换句话说,我需要在行中有兰特、单位、平均价格等,而日期作为列。

我已经阅读了各种示例,但我似乎无法正确理解。 任何帮助将不胜感激!

【问题讨论】:

    标签: sql sql-server pivot unpivot


    【解决方案1】:

    这个会做你想做的,但你必须指定所有的日期

    select
       c.Name,
       max(case when t.DateCreated = '2013-08-26' then c.Value end) as [2013-08-26],
       max(case when t.DateCreated = '2013-08-27' then c.Value end) as [2013-08-27],
       max(case when t.DateCreated = '2013-08-28' then c.Value end) as [2013-08-28],
       max(case when t.DateCreated = '2013-08-29' then c.Value end) as [2013-08-29],
       max(case when t.DateCreated = '2013-08-30' then c.Value end) as [2013-08-30],
       max(case when t.DateCreated = '2013-08-31' then c.Value end) as [2013-08-31],
       max(case when t.DateCreated = '2013-09-01' then c.Value end) as [2013-09-01]
    from test as t
       outer apply (
           select 'Rands', Rands union all
           select 'Units', Units union all
           select 'Average Price', [Average Price] union all
           select 'Success %', [Success %] union all
           select 'Unique Users', [Unique Users]
       ) as C(Name, Value)
    group by c.Name
    

    您可以为此创建动态 SQL,如下所示:

    declare @stmt nvarchar(max)
    
    select @stmt = isnull(@stmt + ',', '') + 
        'max(case when t.DateCreated = ''' + convert(nvarchar(8), t.DateCreated, 112) + ''' then c.Value end) as [' + convert(nvarchar(8), t.DateCreated, 112) + ']'
    from test as t
    
    select @stmt = '
       select
           c.Name, ' + @stmt + ' from test as t
       outer apply (
           select ''Rands'', Rands union all
           select ''Units'', Units union all
           select ''Average Price'', [Average Price] union all
           select ''Success %'', [Success %] union all
           select ''Unique Users'', [Unique Users]
       ) as C(Name, Value)
       group by c.Name'
    
    exec sp_executesql @stmt = @stmt
    

    【讨论】:

    • +1,你需要GROUP BY c.Name,如果你想使用这里是sql fiddle demo
    • @MahmoudGamal 感谢您提醒 group by - 当您不测试查询时很容易错过一些东西:)
    • 谢谢!这不完全是我所需要的(我本来可以在问题中更清楚),但我认为它会让我走上正确的轨道!编辑 - sql fiddle,我不敢相信我不知道这个惊喜!
    【解决方案2】:

    我最终使用动态 sql 解决了这个问题,与标记的答案非常相似。如果没有动态 sql,我无法找到这样做的方法。日期必须按顺序排列,最后 7 天,他们还必须使用星期几的名称(我没有在问题中指定)。

    我需要做的最大改变是将表变量更改为临时表。 这是因为动态 sql 语句在不同的上下文中执行,并且不知道您创建的任何变量。

    最后,我在尝试使用 PIVOT 时完全偏离了轨道,而 APPLY 应该用于存在不止一种“类型”值的情况。

    我在下面提供了我的解决方案,因为它可以帮助遇到类似问题的人:

    CREATE TABLE #SummaryTable
    (
        [DateCreated] DATE UNIQUE,
        [Rands] DECIMAL,
        [Units] INT,
        [Average Price] DECIMAL,
        [Success %] INT,
        [Unique Users] INT
    );
    
    --Code to fill table
    
    declare @stmt nvarchar(max)
    
    select @stmt = isnull(@stmt + ',', '') + 
        'max(case when t.DateCreated = ''' + convert(nvarchar(16), t.DateCreated, 126)
     + ''' then c.Value end) as [' + left(datename(dw, t.DateCreated),3) + ']'
    from #SummaryTable as t
    
    select @stmt = '
       select
           c.Name, ' + @stmt + ' from #SummaryTable as t
       outer apply (
           select ''Rands'', Rands union all
           select ''Units'', Units union all
           select ''Average Price'', [Average Price] union all
           select ''Success'', [Success %] union all
           select ''Unique Users'', [Unique Users]
       ) as C(Name, Value)
       group by c.Name'
    
    exec(@stmt)
    

    【讨论】:

      猜你喜欢
      • 2015-07-23
      • 1970-01-01
      • 1970-01-01
      • 2019-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-04
      • 1970-01-01
      相关资源
      最近更新 更多