关于sql server:通过SQL分配动态列?

Assigning Dynamic Columns via SQL?

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

示例: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

1
2
3
4
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表,但您可以更改它以引用您的真实表。首先是表格:

1
2
3
4
5
6
CREATE TABLE #Test
 (
    [ID] [INT] IDENTITY(1,1) NOT NULL,
    TheDate datetime,
    Harvest INT
 )

然后插入一些虚拟数据:

1
2
3
4
5
6
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)

显示结果:

1
SELECT * FROM #Test

结果是:

1
2
3
4
5
6
7
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

这是神奇发生的地方:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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)

结果:

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

并且不要忘记摆脱临时表

DROP TABLE #Test

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

enter image description here