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

4

3 回答 3

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

于 2013-07-12T10:49:02.563 回答
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
于 2013-07-12T11:00:28.847 回答
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

或者您可以将 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

于 2013-07-12T11:36:52.057 回答