Assigning Dynamic Columns via SQL?
我需要根据两个日期之间减法之前的月数来映射列。
示例:
我需要分配24列(插入临时表),所有月份的名称在
每列代表这样一个月:
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'
结果集将是
有什么建议?
为此,您将需要一个表,而无需使用游标或动态创建列。解决方案是将结果转动以获得最终输出
1 2 | 2010-10 2010-11 2010-12 2011-1... 50 100 25 70 |
也就是说,年份和月份的组合使得该列唯一,并且总和在整个月内完成并放置在正确的列中。快速出现的一个问题是使用
这是您可以做的,我使用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' |
然后执行此查询:
结果:
1 2 | 2011-10 2011-11 2011-12 2012-10 70 200 50 100 |
并且不要忘记摆脱临时表
请记住我正在使用我的测试数据,因此您可以根据需要添加它。这是一切的图形输出: