使用数据透视表填充数据

时间:2013-07-12 10:07:29

标签: sql sql-server-2008 pivot

我有一张这样的表,

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

3 个答案:

答案 0 :(得分: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

上的演示

答案 1 :(得分: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 country=@country and [year]=@year

-- clear
delete from #tempResult

select @counter = @counter + 1
end 

 -- select result
 select * From @result 

 drop table #tempResult

答案 2 :(得分: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