需要动态旋转表制作日期列新表标题

时间:2017-07-20 19:17:00

标签: sql-server tsql pivot

我已经看到互联网上的各种枢轴示例,包括基于文本的教程和视频。没有人能解决手头的问题。

我想要的是转动下表:

销售表

    SalesId  | SalesDate   | SalesLocation  | SalesAmount
    -----------------------------------------------------
     1       | 2012-03     | New York, NY   | 3,000
     2       | 2012-04     | Miami, FL      | 2,500
     3       | 2012-05     | Carmel, CA     | 2,850
     4       | 2012-06     | Berkeley, CA   | 1,900
     5       | 2012-07     | Akron, OH      | 4,200
     6       | 2012-08     | Portland, OR   | 2,200

我想PIVOT这个表将每行显示为,而不是列的明显SUM。每行特别是它自己的列,日期为标题,就好像表格像Excel电子表格一样顺时针旋转了90度,用于日期预测:

    Account Info    | 2012-03      | 2012-04     | 2012-05     | 2012-06
    ---------------------------------------------------------------------
    SalesId         | 1            | 2           | 3           | 4
    SalesLocation   | New York, NY | Miami, FL   | Carmel, CA  | Berkeley, CA
    SalesAmount     | 3,000        | 2,500       | 2,850       | 1,900

关于此主题的大多数教程都涉及创建具有相同城市,相同状态或相同类型的多行的总和。

对于这种情况,每一行都有一个永远不会重复的独特日期,因此所有记录都是唯一的,因此不需要像 SUM 这样的函数。

到目前为止,在观看了一个非常清晰的解决方案后,JoyceW在ASP.net论坛的PIVOT Using Date Column主题上看到了这个问题,我已经做到了这一点:

    declare @cols varchar(max)

    select @cols = (select distinct SalesDate from SalesTable for xml path(''))

    select @cols = replace(@cols, '', '[')
    select @cols = replace(@cols, '', '],')
    select @cols = left(@cols, len(@cols) - 1)

    declare @query varchar(max)

    select @query = 'select * from (select SalesId, SalesLocation, SalesAmount 
    from SalesTable) src pivot (max(SalesAmount) for SalesDate in ('
    + @cols + ')) piv;'

    execute(@query)

虽然这不是我想要的,但它是唯一允许我实际返回结果集的教程,其中顶部列实际上是日期(yay),如下所示:

    SalesId | SalesLocation  | SalesAmount | 2012-03 | 2012-04 | 2012-05 
    1       | New York, NY   | 3,000       | {null}  | {null}  | 4
    2       | Miami, FL      | 2,500       | {null}  | 3       | {null}
    3       | Carmel, CA     | 2,850       | {null}  | {null}  | {null}
    4       | Berkeley, CA   | 1,900       | 1       | {null}  | {null}
    5       | Akron, OH      | 4,200       | {null}  | {null}  | {null}
    6       | Portland, OR   | 2,200       | {null}  | 2       | {null}

不确定这里发生了什么,但它比以前更接近,我实际上收到了结果集。有关如何微调这些行的想法需要旋转或旋转吗?

似乎我只是按照我的意愿转动标题而不是整个表格。任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:1)

如果您想在数据透视表中使用多个聚合列,则必须为每个聚合值执行迭代。我使用Sales作为表名。如果表格名称不同,请更改表格名称。以下查询应该为您提供所需的结果。

DECLARE @cols AS NVARCHAR(MAX),
    @Convertcols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @SQL  AS NVARCHAR(MAX),
    @PivotColumn Varchar(100),
    @i Int = 1,
    @AggColumn Varchar(100)
DECLARE @Columns TABLE (ID int IDENTITY(1,1), AccountInfo Varchar(max))

SELECT @cols = STUFF((SELECT  ', '+ QUOTENAME(SalesDate)
                    from Sales
                    group by SalesDate
                    order by SalesDate
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

SELECT @Convertcols = STUFF((SELECT  ', CAST( '+ QUOTENAME(SalesDate) + ' AS VARCHAR(max)) AS ' + QUOTENAME(SalesDate)
                    from Sales
                    group by SalesDate
                    order by SalesDate
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

INSERT INTO @Columns
SELECT C.name  
FROM SYS.COLUMNS C
INNER JOIN SYS.TABLES  T   ON C.OBJECT_ID = T.OBJECT_ID
WHERE T.NAME = 'Sales'
AND C.name <> 'SalesDate'

While @i <= (SELECT MAX(ID) FROM @Columns)
BEGIN 
SELECT @AggColumn = AccountInfo FROM @Columns Where ID = @i

set @query = 'SELECT AccountInfo,' + @Convertcols +
             ' FROM 
             (
                SELECT ''' + @AggColumn + ''' AS AccountInfo, SalesDate, '+ @AggColumn +' 
                FROM Sales
            ) X
            PIVOT 
            (
                Max('+ @AggColumn +')
                FOR SalesDate in (' + @cols + ')
            ) P '


SET @SQL = CONCAT(@SQL, CHAR(10), CASE WHEN @i = 1 THEN '' ELSE 'UNION ' END, CHAR(10) , @query) 
SET @i = @i+1  

END 

EXECUTE (@SQL)

结果:

enter image description here

答案 1 :(得分:0)

为了让你能够PIVOT,你需要至少有一个非旋转的列 - 这是你的模型所缺乏的。

  

文档:https://technet.microsoft.com/en-us/library/ms177410%28v=sql.105%29.aspx?f=255&MSPPError=-2147217396