代码之家  ›  专栏  ›  技术社区  ›  Vinh Ton

是否可以在不显式命名SQL Server中的每一列的情况下进行多个数据透视?

  •  1
  • Vinh Ton  · 技术社区  · 7 年前

    enter image description here

    我的挑战是:

    1. 如果不显式地将数据透视列重命名为“in(…)”,怎么办?
    2. 为多个枢轴集成该解决方案

    这是我目前掌握的代码:

    PIVOT 
        (SUM([Revenue])
           FOR [Year Month] IN ([201710], [201711]) 
        ) AS Pivot1
    
    PIVOT 
        (SUM([Gross Profit])
           FOR [Year Month] IN ([201710], [201711])  
        ) AS Pivot2
    
    3 回复  |  直到 7 年前
        1
  •  2
  •   Joel Coehoorn    7 年前

    SQL语言具有 你知道前面每列的数量和类型。查询优化器/数据库引擎需要这一点,以便构建高效的执行计划并评估查询中使用的列的权限。甚至使用 SELECT * 满足此要求,因为在查询的其余部分中使用的任何给定表或视图中的列数是固定的和已知的(至少在该查询的生命周期内)。

    您所要求的内容要求结果中的列数由数据确定,直到 之后 创建执行计划。这是不允许的。实现这一点的唯一方法是通过动态SQL,其中有三个步骤。首先运行SELECT以获取所需的列。然后使用该数据动态构建新的查询字符串。最后,执行刚刚构建的查询字符串并将数据返回给用户。

        2
  •  0
  •   Lukasz Szozda    7 年前

    通常,如果没有动态SQL,您没有很多选项。您需要在中使用别名 SELECT col as alias .

    在Oracle中,您可以通过以下方式获得更好的结果:

    SELECT *
    FROM  source
    PIVOT (SUM(Revenue) AS Revenue, SUM(Profit) AS Profit 
           FOR (YearMonth) IN (201801, 201802)) s;
    

    DBFiddle Demo

        3
  •  0
  •   Nolan Shang    7 年前

    我不明白你的目标,为什么B的201802收入会在201801收入中回归。

         if object_id('tempdb..#t') is not null drop table #t
        go
        create table #t(Customer varchar(100),[Date] varchar(100),Revenue int,Profit int)
        insert into #t(Customer,[Date],Revenue,Profit)
        select 'a','201801',100,1 union all
        select 'a','201801',10,11 union all
        select 'b','201802',200,20
    
        declare @sql nvarchar(max),@cols nvarchar(max)
        select @cols=isnull(@cols+',','')+quotename('Revenue '+[Date])+','+quotename('Profit '+[Date]) from #t group by [date]
    
        set @sql='
        select * from (
        select customer,colname,colvalue 
        from #t
        cross apply(values(''Revenue ''+[Date],Revenue),(''Profit ''+[Date],Profit)) c(colName,ColValue)
        ) as t pivot (sum(colvalue) for colname in ('+@cols+')) p'
        exec(@sql)
    
    +----------+----------------+---------------+----------------+---------------+
    | customer | Revenue 201801 | Profit 201801 | Revenue 201802 | Profit 201802 |
    +----------+----------------+---------------+----------------+---------------+
    | a        | 110            | 12            | NULL           | NULL          |
    | b        | NULL           | NULL          | 200            | 20            |
    +----------+----------------+---------------+----------------+---------------+