首页 文章

通过SQL分配动态列?

提问于
浏览
2

我需要根据两个日期之间减法之前的月数来映射列 .

示例: 2012-10-01 - 2010-10-01 = 24

我需要分配24列(插入临时表),所有月份的名称在 01.10.201201.10.2010 => 10月,11月,..... 10月之间 .

每列代表一个月,如下所示:

10月11月12月1月2月3月4月5月6月7月8月9月10月11月12月1月2月3月4月5月6月7月8月9月10月

table_Temporal

City    
Area    
Production => Oct,Nov,Dec...etc...
Yield

好吧,根据一个叫做“收获月份”的时间,我有一个名为“ 生产环境 ”的数字,我按月显示分布情况 .

例:

生产环境 =>收获日期100 =>'2010 / 10/02'200 =>'2011/11 / 01'100 =>'2012 / 10/10'

结果集将是

enter image description here

有什么建议?

1 回答

  • 2

    为此,您将需要一个表,而无需使用游标或动态创建列 . 解决方案是将结果转动以获得最终输出

    2010-10  2010-11 2010-12 2011-1...
      50      100     25       70
    

    也就是说,年份和月份的组合使得列唯一,并且总和在整个月内完成并放置在正确的列中 . 快速出现的一个问题是当使用 PIVOT 时,您需要列出您的列名称 . 例如 ... PIVOT (SUM(Harvest)) FOR ([2011-10], [2011-11]... 但我们可以使用 STUFFXML Path 来避免这一切 .

    这是您可以做的,我使用TEMP表,但您可以更改它以引用您的真实表 . 首先是表格:

    CREATE TABLE #Test
     (
        [ID] [int] IDENTITY(1,1) NOT NULL,
        TheDate datetime,
        Harvest int
     )
    

    然后插入一些虚拟数据:

    INSERT INTO #Test(TheDate, Harvest) VALUES ('10/11/2011', 50)
    INSERT INTO #Test(TheDate, Harvest) VALUES ('10/11/2012', 100)
    INSERT INTO #Test(TheDate, Harvest) VALUES ('10/1/2011', 20)
    INSERT INTO #Test(TheDate, Harvest) VALUES ('12/11/2011', 50)
    INSERT INTO #Test(TheDate, Harvest) VALUES ('11/11/2011', 50)
    INSERT INTO #Test(TheDate, Harvest) VALUES ('11/12/2011', 150)
    

    显示结果:

    SELECT * FROM #Test
    

    结果是:

    ID   TheDate                 Harvest
    1   2011-10-11 00:00:00.000 50
    2   2012-10-11 00:00:00.000 100
    3   2011-10-01 00:00:00.000 20
    4   2011-12-11 00:00:00.000 50
    5   2011-11-11 00:00:00.000 50
    6   2011-11-12 00:00:00.000 150
    

    这是神奇发生的地方:

    DECLARE @listCol VARCHAR(2000)
    DECLARE @query VARCHAR(4000)
    
    SELECT  @listCol = STUFF((  
                              SELECT DISTINCT
                              ],[' + ltrim(str(YEAR(TheDate))) + 
                              '-' + CAST (MONTH(TheDate) as varchar(50))
                              FROM    
                       #Test
                      ORDER BY 
                    '],[' + ltrim(str(YEAR(TheDate))) + '-' + 
                                CAST(MONTH(TheDate) as varchar(50))
                                FOR XML PATH('')
                                        ), 1, 2, '') + ']'
    SET @query = 
    'SELECT * FROM
          (SELECT 
                 ltrim(str(YEAR(TheDate))) + 
                 ''-'' + CAST (MONTH(TheDate) as varchar(50)) AS TheCol, 
                 Harvest
                FROM 
                 #Test
                ) src
            PIVOT (SUM(Harvest) FOR TheCol
            IN ('+@listCol+')) AS pvt'
    

    然后执行此查询:

    EXECUTE (@query)

    结果:

    2011-10    2011-11     2011-12    2012-10
    70          200         50    100
    

    并且不要忘记摆脱临时表

    DROP TABLE #Test

    请记住我正在使用我的测试数据,因此您可以根据需要添加它 . 这是一切的图形输出:

    enter image description here

相关问题