我有一张这样的表,
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中执行此操作。
答案 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;
或者你可以使用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;
这也可以使用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;