2013-07-12 143 views
3

我有一个这样的表填充数据,使用数据透视表

country 2007 2008 2009 
UK  5  10  20 
uk  5  10  20 
us  10  30  40 
us  10  30  40 

但我想填充这样的表,

country year Total volumn 
uk  2007 10 
uk  2008 20 
uk  2009 40 
us  2007 20 
us  2008 60 
us  2009 80 

如何使用我做这在SQL Server 2008数据透视表或任何其他方法。

http://sqlfiddle.com/#!3/2499a

+0

可以发布更多详情请,但在()在读入数据透视先验货() – RoughPlace

回答

5
SELECT country, [year], SUM([Total volumn]) AS [Total volumn] 
FROM (
     SELECT country, [2007], [2008], [2009] 
     FROM dbo.test137 
    ) p 
UNPIVOT 
([Total volumn] FOR [year] IN ([2007], [2008], [2009]) 
) AS unpvt 
GROUP BY country, [year] 
ORDER BY country, [year] 

观看演示上SQLFiddle

+0

非常好。可能需要添加ORDER BY country,year才能按照指定目标查看订单中的结果。 –

+0

好评@Der U.答案已更新。谢谢 –

2

请尝试以下 - 记得要改变[DB]用自己的数据库名称。在我的例子中,你不需要写年,但是它们会自动为你提取。

-- will contain the temporary total 
create table #tempResult (total int) 

-- get all countries 
declare @countries table (country varchar(50)) 
insert into @countries 
select country from table1 

-- get all years 
declare @years table(id int identity(1,1), [year] int) 
insert into @years 
SELECT column_name 
FROM [DB].INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = N'Table1' 
and column_name != 'country' 

-- get all combinations 
declare @result table(id int identity(1,1),country varchar(50),[year] int,total int) 
insert into @result 
select distinct upper(c.country),y.[year],0 
from @years as y,@countries as c 

-- will be used for the looping 
declare @counter int 
select @counter = 1 

while @counter <= (select count(*) from @result) 
begin 

declare @year int 
declare @country varchar(50) 

-- get year and country in question 
select @year = [year] from @result where id = @counter 
select @country = country from @result where id = @counter 

declare @total int 
select @total = (select sum(@year) from table1 where country = @country) 

-- insert temp result 
declare @sql nvarchar(max) 
set @sql = N'insert into #tempResult select sum([' + cast(@year as varchar(50)) + ']) from table1 where country = ''' + @country + '''' 
print @sql 

exec (@sql) 

-- extract 
select top 1 @total = total from #tempResult 

-- update respectively 
update @result set total = @total 
where [email protected] and [year][email protected] 

-- clear 
delete from #tempResult 

select @counter = @counter + 1 
end 

-- select result 
select * From @result 

drop table #tempResult 
2

由于您使用的是SQL Server 2008+,因此您可以使用CROSS APPLY将列中的数据反转为行。

您可以使用VALUES子句与CROSS APPLY:

select distinct t.country, 
    c.year, 
    c.totalvolumn 
from yourtable t 
cross apply 
(
    values 
    ('2007', 2007), 
    ('2008', 2008), 
    ('2009', 2009) 
) c(year, TotalVolumn) 
order by t.country, c.year; 

SQL Fiddle with Demo

或者你可以使用UNION ALL与CROSS APPLY:

select distinct t.country, 
    c.year, 
    c.totalvolumn 
from yourtable t 
cross apply 
(
    select '2007', 2007 union all 
    select '2008', 2008 union all 
    select '2009', 2009 
) c(year, TotalVolumn) 
order by t.country, c.year; 

SQL Fiddle with Demo

这也可以使用UNION查询写着:

select country, '2007' year, 2007 totalVolumn 
from yourtable 
union 
select country, '2008' year, 2008 totalVolumn 
from yourtable 
union 
select country, '2009' year, 2009 totalVolumn 
from yourtable 
order by country, year; 

SQL Fiddle with Demo