下图是我的表
以下excel是输出设计。
我的表包含每月12列和年份列。一个项目,它可以在多年内提供,每个月都有数据。
year- itemcode- jan- feb
2014- pqr- 12- 11
2015- pqr- 4- 8
我需要生成以下输出。对于可用多年的项目 输出需要按以下方式列出。
ItemCode- Jan14- Feb14- Mar14-... Dec14- Jan15- Feb15-... Dec15
pqr- 12- 11- 4- 8-
我怎样才能实现这一目标。 我在google搜索后尝试了不同的方法。但是我无法得到适当的输入来解决这个问题。 目前我正在尝试在SO中找到一些解决方案。有人可以提供一些意见非常有帮助。提前谢谢。
答案 0 :(得分:1)
假设您有下表:
select 'AA' as ItemCode,2014 as year, 23 as Jan, 55 as Feb, 55 as Mar,565 as Apr,656 as May,
343 as Jun,54 as Jul,23 as Aug,66 as Sep,645 as Oct,32 as Nov,66 as Dec
into dbo.test ;
insert into dbo.test select 'AA',2015,554,456,3,54,756,98,2,765,24,876,34,66
union select 'BB',2014,45,56,3,54,756,98,2,765,24,876,34,66
union select 'BB',2015,45,56,3,54,756,98,2,765,24,876,34,66;
使用动态sql,执行
declare @sql nvarchar(1000);
declare @sql2 nvarchar(1000);
declare @year int;
declare @first_year int;
declare c cursor for select distinct year from dbo.test;
open c;
FETCH NEXT FROM c into @year
if @@FETCH_STATUS = 0
begin
select @sql='select test'+convert(varchar,@year)+'.ItemCode';
select @sql = @sql+',test'+CONVERT(varchar,@year)+'.Jan as Jan'+CONVERT(varchar,@year)+',test'
+CONVERT(varchar,@year)+'.Feb as Feb'+CONVERT(varchar,@year)+',test'
+CONVERT(varchar,@year)+'.Mar as Mar'+CONVERT(varchar,@year);
select @sql2='test test'+CONVERT(varchar,@year);
select @first_year=@year;
end;
FETCH NEXT FROM c into @year
WHILE @@FETCH_STATUS = 0
begin
select @sql = @sql+',test'+CONVERT(varchar,@year)+'.Jan as Jan'+CONVERT(varchar,@year)+',test'
+CONVERT(varchar,@year)+'.Feb as Feb'+CONVERT(varchar,@year)+',test'
+CONVERT(varchar,@year)+'.Mar as Mar'+CONVERT(varchar,@year);
select @sql2=@sql2+' inner join test test'+CONVERT(varchar,@year)+' on test'+CONVERT(varchar,@year)+'.ItemCode=test'+CONVERT(varchar,@first_year)+'.ItemCode and test'+CONVERT(varchar,@year)+'.year='+CONVERT(varchar,@year);
FETCH NEXT FROM c into @year
end;
close c;
deallocate c;
select @sql=@sql+' FROM '+@sql2 + ' AND test'+convert(varchar,@first_year)+'.year='+CONVERT(varchar,@year);
print @sql
EXECUTE sp_executesql @sql;
或者,使用标准SQL,类似这样的
select test2014.ItemCode,test2014.Jan as Jan2014,test2014.Feb as Feb2014,test2015.Jan as Jan2015,test2015.Feb as Feb2015
from test test2014 inner join test test2015 on test2014.ItemCode=test2015.ItemCode
where test2014.year=2014 and test2015.year=2015;
答案 1 :(得分:1)
您需要使用动态SQL ...
基本上假设一个名为#tbl的表(带有一点样本数据 - 我只做了3个月但延伸到12个!)
CREATE TABLE #tbl ([ItemCode] NVARCHAR(20), [Year] INT, Jan INT, Feb INT, Mar INT)
INSERT #tbl ( ItemCode, Year, Jan, Feb, Mar )
VALUES ( 'pqr', 2014, 12, 11, 7 ), ( 'pqr', 2015, 4, 8, 0 ),
( 'xyz', 2015, 7, 1, 0 ), ( 'abc', 2013, 63, 23, 12 ), ( 'abc', 2015, 63, 23, 12 )
我们希望生成一个类似于
的查询SELECT tbase.ItemCode
, ISNULL(t13.Jan,0) AS 'Jan-13', ISNULL(t13.Feb,0) AS 'Feb-13', ISNULL(t13.Mar,0) AS 'Mar-13'
, ISNULL(t14.Jan,0) AS 'Jan-14', ISNULL(t14.Feb,0) AS 'Feb-14', ISNULL(t14.Mar,0) AS 'Mar-14'
, ISNULL(t15.Jan,0) AS 'Jan-15', ISNULL(t15.Feb,0) AS 'Feb-15', ISNULL(t15.Mar,0) AS 'Mar-15'
FROM
(SELECT DISTINCT(ItemCode) AS ItemCode FROM #tbl) AS tbase
LEFT JOIN (SELECT * FROM #tbl AS t13 WHERE YEAR = 2013) AS t13 ON t13.ItemCode = tbase.ItemCode
LEFT JOIN (SELECT * FROM #tbl AS t14 WHERE YEAR = 2014) AS t14 ON t14.ItemCode = tbase.ItemCode
LEFT JOIN (SELECT * FROM #tbl AS t15 WHERE YEAR = 2015) AS t15 ON t15.ItemCode = tbase.ItemCode
结果如:
ItemCode Jan-13 Feb-13 Mar-13 Jan-14 Feb-14 Mar-14 Jan-15 Feb-15 Mar-15
abc 63 23 12 0 0 0 63 23 12
pqr 0 0 0 12 11 7 4 8 0
xyz 0 0 0 0 0 0 7 1 0
正如您从查询中看到的那样,要构建的两件事是行, ISNULL(t13.Jan,0)...
和LEFT JOIN (SELECT ...
我们可以通过声明2个NVARCHAR(MAX)
变量(一个用于select,一个用于from)并在while循环中构建它们,同时迭代可用年份来完成此操作。
即... ...
DECLARE @select NVARCHAR(MAX);
DECLARE @from NVARCHAR(MAX);
DECLARE @years TABLE(yr INT);
DECLARE @year INT;
DECLARE @yearName NVARCHAR(2)
INSERT @years
SELECT DISTINCT [Year] FROM #tbl
SELECT @year = MIN(yr) FROM @years
SELECT @yearName = RIGHT(CAST(@year AS NVARCHAR(4)),2)
SELECT @select = 'SELECT tbase.ItemCode'
SELECT @from = 'FROM (SELECT DISTINCT(ItemCode) AS ItemCode FROM #tbl) AS tbase '
WHILE EXISTS (SELECT NULL FROM @years WHERE yr = @year)
BEGIN
SELECT @yearName = RIGHT(CAST(@year AS NVARCHAR(4)),2)
SELECT @select = @select + CHAR(13) + CHAR(10)
+ ', ISNULL(t' + @yearName + '.Jan,0) AS [Jan-' + @yearName + '],'
+ ' ISNULL(t' + @yearName + '.Feb,0) AS [Feb-' + @yearName + '],'-- +9 more
+ ' ISNULL(t' + @yearName + '.Mar,0) AS [Mar-' + @yearName + '] '
SELECT @from = @from + CHAR(13) + CHAR(10)
+ 'LEFT JOIN (SELECT * FROM #tbl AS t' + @yearName
+ ' WHERE [Year] = ' + CAST(@year AS NVARCHAR(4)) + ') AS t' + @yearName
+ ' ON t' + @yearName + '.ItemCode = tbase.ItemCode '
SELECT @year = @year + 1
END
DECLARE @sql NVARCHAR(MAX)
SELECT @sql = @select + CHAR(13) + CHAR(10) + @from
EXEC (@sql)
您需要做的就是将其延长至整整12个月,然后您就完成了!
注意 - 我认为每年至少有一个条目。如果您的范围中间有一年没有任何条目,您需要对WHILE循环进行微小修改 - 即WHILE @year <= (SELECT MAX(Year) FROM @years)