2017-07-20 18 views
2

我已经在互联网上看到了几乎所有的示例,包括基于文本的教程和视频。没有人在解决这个问题。需要动态数据透视表制作日期列新表头

我要的是如下表转动:

销售表

 
    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列。每一行是专门它自己的专栏,与日期为,仿佛表已经变成顺时针旋转90度像Excel电子表格,日期预测:

 
    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) 

虽然这不是我一直在寻找,这是这使我真正返回结果集,其中顶列实际上是日期(耶),如下所示的唯一教程:

 
    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} 

不是真的知道是什么回事,但它是一个很多CLO比我之前的系列,我实际上收到了一个结果集。关于如何微调显示的行需要旋转或旋转的任何想法?

看来,我只是旋转标题,而不是我想要的整个表。任何建议将不胜感激。

+1

'选择@cols =(选择di'是不是Oracle语法,它是SQL的服务器请正确的标签在你的问题,所以你会得到帮助更快。 。 – krokodilko

+1

我的答案适合你吗?或者你正在寻找别的东西? – CuriousKid

+0

@CuriousKid我现在正在尝试。我完成后会立即发送消息(和解决方案投票)。谢谢您的回答! –

回答

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

+0

伟大的设计模式。但是,当我运行此查询(将其修改为我的数据库列属性后)时,由于INSERT命令,我只看到“xx rows affected”消息,而没有显示在图像附件上的输出。 –

+0

你能显示你修改的内容吗?它在结果窗格 上显示什么? – CuriousKid

+0

简单的错字在我的结尾。这工作。这是一个很大的帮助。请PM我。 –