Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
动态列-SQL Server-月份作为列_Sql_Sql Server_Sql Server 2005_Tsql_Ssis - Fatal编程技术网

动态列-SQL Server-月份作为列

动态列-SQL Server-月份作为列,sql,sql-server,sql-server-2005,tsql,ssis,Sql,Sql Server,Sql Server 2005,Tsql,Ssis,数据库:SQL Server 2005 我们有一个以这种方式包含数据的表: Project Year Jan Feb Mar Apr May Jun Jul Aug Sep

数据库:SQL Server 2005

我们有一个以这种方式包含数据的表:

Project              Year        Jan                   Feb                   Mar                   Apr                   May                   Jun                   Jul                   Aug                   Sep                   Oct                   Nov                   Dec
-------------------- ----------- --------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------------------- --------------------- ---------------------
11-11079             2008        0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  75244.90
11-11079             2009        466.00                0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00
11-11079             2010        855.00                0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00                  0.00  
01-11052             2009        56131.00              0.00                  36962.00              -61596.00             2428.00               84.00                 0.00                  0.00                  0.00                  0.00                  0.00                  0.00
有人希望数据显示为整个项目的一行。这些列将是动态的,这取决于未来的年数。例如:

Project        Jan-2009     Feb-2009     Mar-2009     Apr-2009... Dec-2009     Jan-2010
-------------- ------------ ------------ ------------ ----------- ------------ ---------
11-11079       466.00       0.00         0.00         0.00        0.00         855.00    
01-11052       56131.00     0.00         36962.00     -61596.00   2428.00      0.00
我读过很多例子,其中每个条目的日期填充在一列中,但我没有发现任何以月份为列名、以年份为行的情况

具有透视表的动态SQL?
或者使用SQL、临时表、联接和联合进行大规模操作?

关于使用SSIS透视表功能有什么想法吗?

我认为可以使用嵌套的while循环和一些动态SQL来实现。如果无法保存最终表,或者必须每月重新生成所有列,那么这将是一个缓慢的解决方案。然而,如果它只是一个加法,那么它可能并不坏。无论如何,我会这样做:

  • Out loop选择最古老的年份
  • 内部循环选择第一个月
  • 内部循环-向表中添加名为的列
  • 使用动态SQL在内部循环中更新表,其中包含新列的所有信息
  • 对每个月的内部循环进行迭代
  • 每年迭代外部循环

  • 您的数据已进行数据透视,但需要在不同级别进行数据透视。我认为处理这个问题的最好方法是先取消pivot,然后再处理正确的pivot级别

    步骤1:取消PIVOT

    您可以使用SQL2005命令,也可以使用交叉连接技术。这里有两个例子。注意我在中间放了几个月让事情变得简单。把它们加进去就行了

    -- CROSS JOIN method (also works in SQL 2000)
    SELECT
       P.Project,
       Mo =
          DateAdd(mm,
             X.MonthNum,
             DateAdd(yy, P.[Year] - 1900, '19000101')
          ),
       Amount = 
          CASE X.MonthNum
             WHEN 0 THEN Jan
             WHEN 1 THEN Feb
             WHEN 11 THEN Dec
          END
    FROM
       ProjectData P
       CROSS JOIN (
          SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 11
       ) X (MonthNum)
    
    每行重复12次,然后CASE语句只为每行提取一个月的数据,使数据很好地未插入

    -- UNPIVOT method
    SELECT
        P.Project,
        Mo =
           DateAdd(mm,
              Convert(int, P.MonthNum),
              DateAdd(yy, P.[Year] - 1900, '19000101')
           ),
        P.Amount
    FROM
       (
          SELECT Project, [Year], [0] = Jan, [1] = Feb, [11] = Dec
          FROM ProjectData
       ) X UNPIVOT (Amount FOR MonthNum IN ([0], [1], [11])) P
    
    DROP TABLE ProjectData
    
    这两种方法都不是一直以来的性能赢家。有时一个比另一个工作得更好(取决于数据透视)。UNPIVOT方法在执行计划中使用交叉联接不使用的筛选器

    第2步:再次旋转

    现在,如何使用未插入的数据。您没有说您的某人将如何使用这些数据,但由于您需要将数据放入某种输出文件中,因此我建议使用Sql Server 2005附带的SSRS(Sql Server Reporting Services),无需额外收费

    只需使用报表对象来透视上面的一个查询。这个对象很高兴地确定了要在报表运行时生成列标签的数据值,听起来正是您所需要的。如果添加的列格式与您喜欢的日期格式完全一致,则可以按Mo列排序,但可以使用新表达式作为列标签

    SSRS还提供多种格式和调度选项。例如,您可以让它通过电子邮件发送Excel文件或将网页保存到文件共享

    如果我遗漏了什么,请告诉我

    对于希望看到上述代码实际运行的任何人,这里有一些创建脚本供您使用:

    USE tempdb
    
    CREATE TABLE ProjectData (
        Project varchar(10),
        [Year] int,
        Jan decimal(15, 2),
        Feb decimal(15, 2),
        Dec decimal(15, 2)
    )
    
    SET NOCOUNT ON
    
    INSERT ProjectData VALUES ('11-11079', 2008, 0.0, 0.0, 75244.90)
    INSERT ProjectData VALUES ('11-11079', 2009, 466.0, 0.0, 0.0)
    INSERT ProjectData VALUES ('11-11079', 2010, 855.0, 0.0, 0.0)
    INSERT ProjectData VALUES ('01-11052', 2009, 56131.0, 0.0, 0.0)
    

    我编写了一个名为pivot\u query的存储过程,它可以帮助解决这个问题,源代码是,原始数据示例


    不精确,但非常接近。:-)

    请不要在标题或问题中使用术语“MS SQL”。没有这样的产品。使用它会使搜索很难找到您的问题,并且会混淆SQL Server和MySQL之间的关系。嘿-我忽略了我知道答案的tsql问题,因为我将MSSQL理解为MySQLJohn-这些名称很接近,也很混乱,但公平地说,在这里发布的人,Microsoft SQL Server在某种程度上被称为MSSQL。请查看二进制文件的路径:-)C:\Program Files\Microsoft SQL Server\MSSQLS10.TEST2008\MSSQL或PowerShell>Get Service,至少对我来说,它会生成MSSQL$TEST2008作为服务的名称。@OnUpdate Cascade:文件夹的名称与产品的名称不相等。我也不是在责怪他们或其他什么——我是在解释为什么不在这里使用这个词。我想如果你能说
    SQL Server
    是一个非常糟糕的SQL Server名称,不管它多么贴切
    MSSQL
    当然更具描述性,并将排除其他内容(如本消歧页上列出的内容:)。更不用说它有这种傲慢的权威声音,不能很好地代表产品或竞争对手的替代品。很抱歉,RandomBen,当基于集合的解决方案清晰易用,可用于取消激励,然后再次旋转时,根本不支持循环。循环的性能将非常糟糕。我忘了添加5月份,但不允许我编辑帖子以将其放入。:-)天哪,罗恩。当基于集合的代码和现有SQL Server工具可以解决问题时,为什么还要使用大量的过程代码?它是通用的,适用于任何查询,而不必知道数据透视列的值。在许多“数据透视”样式的报告中为我们节省了大量开发人员时间。我不是为了这个才写的。:-)@罗恩·萨维奇:罗恩,我也有类似的代码,我花了很多时间在一些更通用的程序代码上,以解决重复出现的问题。然而。。。SSRS矩阵报表控件也是“通用的,可以用于任何查询,而不必知道数据透视列的值。”既然你说你是为报表而做的,我无法想象为什么当SSR可以开箱即用时,有人会想使用过程代码。不是我们所有的应用程序都可以访问或需要使用报表服务器。我们也有使用矩阵的报表,并且我们发现,对于旋转大型结果集,此过程要快得多,因为只有汇总的结果发送到报表服务器,而不是控件要旋转和汇总的所有原始数据。我不知道你为什么打电话来
    With your data:
    
    create table ProjectData
       (
       Project                      varchar(20),
       [Year]                       Integer,
       Jan                          decimal(12,2),
       Feb                          decimal(12,2),
       Mar                          decimal(12,2),
       Apr                          decimal(12,2),
       May                          decimal(12,2),
       Jun                          decimal(12,2),
       Jul                          decimal(12,2),
       Aug                          decimal(12,2),
       Sep                          decimal(12,2),
       Oct                          decimal(12,2),
       Nov                          decimal(12,2),
       Dec                          decimal(12,2)
       );
    
    insert into ProjectData values ('11-11079',2008, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 75244.90);
    insert into ProjectData values ('11-11079',2009, 466.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00);
    insert into ProjectData values ('11-11079',2010, 855.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00) ;
    insert into ProjectData values ('01-11052',2009, 56131.00, 0.00, 36962.00, -61596.00, 2428.00, 84.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00);
    
    declare @mySQL varchar(MAX)
    
    set @mySQL = 'select * from ProjectData'
    
    exec pivot_query @mySQL, 'Project', 'Year', 'max(Jan) Jan,max(Feb) Feb,max(Mar) Mar,max(Apr) Apr,max(Jun) Jun,max(Jul) Jul,max(Aug) Aug,max(Sep) Sep,max(Oct) Oct,max(Nov) Nov,max(Dec) Dec'
    
    Results:
    Project              2008_Jan     2008_Feb     2008_Mar     2008_Apr     2008_Jun     2008_Jul     2008_Aug     2008_Sep     2008_Oct     2008_Nov     2008_Dec     2009_Jan     2009_Feb     2009_Mar     2009_Apr     2009_Jun     2009_Jul     2009_Aug     2009_Sep     2009_Oct     2009_Nov     2009_Dec     2010_Jan     2010_Feb     2010_Mar     2010_Apr     2010_Jun     2010_Jul     2010_Aug     2010_Sep     2010_Oct     2010_Nov     2010_Dec
    -------------------- ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------
    01-11052             NULL         NULL         NULL         NULL         NULL         NULL         NULL         NULL         NULL         NULL         NULL         56131.00     .00          36962.00     -61596.00    84.00        .00          .00          .00          .00          .00          .00          NULL         NULL         NULL         NULL         NULL         NULL         NULL         NULL         NULL         NULL         NULL
    11-11079             .00          .00          .00          .00          .00          .00          .00          .00          .00          .00          75244.90     466.00       .00          .00          .00          .00          .00          .00          .00          .00          .00          .00          855.00       .00          .00          .00          .00          .00          .00          .00          .00          .00          .00